persistence.cpp:2197:ann.xml(1): There should be space between attributes in function icvXMLParseTag

August 3, 2016
作者:dengshuai_super
出处:http://blog.csdn.net/dengshuai_super/article/details/52069634
声明:转载请注明作者及出处。


注意⚠️:此问题还不算解决,只是暂时用了别人的库,以后解决了,会回来记录。因为我是做笔记,所以建议大家直接看文章最后。
Opencv3.1.0 , Ubuntu16.04 ,开发板Microzed和Zedboard都试过了,出现同样问题。


charVec size:101
file /home/ds/build/opencv-3.1.0/modules/core/src/persistence.cpp, line 2197 terminate called after throwing an instance of 'cv::Exception' 
what():/home/ds/build/opencv-3.1.0/modules/core/src/persistence.cpp:2197:error:(-212) /mnt/PRTest/resources/model/ann.xml(1):
There should be space between attributes in function icvXMLParseTag

http://www.th7.cn/Program/cp/201605/851893.shtml

/** @brief Loads algorithm from the file

     @param filename Name of the file to read.
     @param objname The optional name of the node to read (if empty, the first top-level node will be used)

     This is static template method of Algorithm. It's usage is following (in the case of SVM):
     @code
     Ptr svm = Algorithm::load("my_svm_model.xml");
     @endcode
     In order to make this method work, the derived class must overwrite Algorithm::read(const
     FileNode& fn).
*/

    template static Ptr<_Tp> load(const String& filename, const String& objname=String())
    {
        FileStorage fs(filename, FileStorage::READ);
        FileNode fn = objname.empty() ? fs.getFirstTopLevelNode() : fs[objname];
        Ptr<_Tp> obj = _Tp::create();
        obj->read(fn);
        return !obj->empty() ? obj : Ptr<_Tp>();
    }
  /** @brief Reads algorithm parameters from a file storage
    */
    virtual void read(const FileNode& fn) { (void)fn; }

    /** @brief Reads algorithm from the file node

     This is static template method of Algorithm. It's usage is following (in the case of SVM):
     @code
     Ptr svm = Algorithm::read(fn);
     @endcode
     In order to make this method work, the derived class must overwrite Algorithm::read(const
     FileNode& fn) and also have static create() method without parameters
     (or with all the optional parameters)
     */
    template static Ptr<_Tp> read(const FileNode& fn)
    {
        Ptr<_Tp> obj = _Tp::create();
        obj->read(fn);
        return !obj->empty() ? obj : Ptr<_Tp>();
    }

http://stackoverflow.com/questions/25831111/opencv-traincascade-build-intermediate-result/26301531#26301531

猜测一:xml本身出现了错误

Ubuntu 里面:/home/ds/桌面/EasyPR-master/resources/model/ann.xml


<!opencv_storage>
<opencv_ml_ann_mlp>
  <format>3format>
  <layer_sizes>120 40 65layer_sizes>
  <activation_function>SIGMOID_SYMactivation_function>
  <f_param1>1.f_param1>
  <f_param2>1.f_param2>

我故意把第二行加了一个”!”,Ubuntu里运行程序:出现:

OpenCV Error: Parsing error (resources/model/ann.xml(2):
file /home/ds/opencv-3.1.0/modules/core/src/persistence.cpp, 
 line 2249 terminate called after throwing an instance of 'cv::Exception'
  what():  /home/ds/opencv-3.1.0/modules/core/src/persistence.cpp:2249: 
  error: (-212) resources/model/ann.xml(2): 
   tag is missing in function icvXMLParse

在已经做好opencv移植的arm linux里面运行,出现:

OpenCV Error: Parsing error (resources/model/ann.xml(1): 
There should be space between attributes) in icvXMLParseTag, 
file /home/ds/build/opencv-3.1.0/modules/core/src/persistence.cpp, line 2197 what():  
  /home/ds/build/opencv-3.1.0/modules/core/src/persistence.cpp:2197: error: (-212) resources/model/ann.xml(1):
   There should be space between attributes in function icvXMLParseTag

然后我只把ann.xml 的第一行改为

在arm linux 报错和Ubuntu 上一样:

OpenCV Error: Parsing error (resources/model/ann.xml(1): Attribute name should be followed by '=') in icvXMLParseTag, 
file /home/ds/build/opencv-3.1.0/modules/core/src/persistence.cpp, 
line 2149 terminate called after throwing an instance of 'cv::Exception' what():  
/home/ds/build/opencv-3.1.0/modules/core/src/persistence.cpp:2149: 
error: (-212) resources/model/ann.xml(1): Attribute name should be followed by '=' in function icvXMLParseTag

我把ann.xml 的第一行改为

arm linux显示错误:

OpenCV Error: Parsing error (resources/model/ann.xml(1): 
There should be space between attributes) in icvXMLParseTag, 
file /home/ds/build/opencv-3.1.0/modules/core/src/persistence.cpp, 
line 2197 terminate called after throwing an instance of 'cv::Exception' what():  /home/ds/build/opencv-3.1.0/modules/core/src/persistence.cpp:2197: 
error: (-212) resources/model/ann.xml(1): 
There should be space between attributes in function icvXMLParseTag

结果arm上没检测出最右边?的问题,Ubuntu检测出来了。

于是我用opencv官方的例子人脸识别的那个(FaceDetection),在Ubuntu上可以顺利跑起来,移植到arm 上之后,出现了同样的问题:

WARNING: Could not load classifier cascade for nested objects OpenCV Error: 
There should be space between attributes) in icvXMLParseTag, 
file /home/ds/build/opencv3.1.0/modules/core/src/persistence.cpp, line 2197
terminate called after throwing an instance of 'cv::Exception'
    what():  /home/ds/build/opencv-3.1.0/modules/core/src/persistence.cpp:2197: error: (-212) haarcascade_frontalface_alt.xml(1): 
    There should be space between attributes in function icvXMLParseTag

Aborted

说明这是通性的问题,正确的在Ubuntu上可以用的xml,移植到开发板上的arm linux里面时,就会出现
There should be space between attributes in function icvXMLParseTag 的问题。

猜测二:是arm上解析出现问题

开始时我怀疑是缺少libxml2库的问题导致了解析失败:(其实后来发现opencv是用自己的解析函数来解析xml)
于是我用ldd命令看Ubuntu程序链接了哪些库:
其中发现了xml2

 ldd demo_linux_amd64 

打印出:

linux-vdso.so.1 =>  (0x00007ffdeb3b3000)
   `libopencv_world.so.3.1 => /usr/local/lib/libopencv_world.so.3.1 (0x00007f62e0ffe000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f62e0c61000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f62e0957000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f62e0741000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f62e0378000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f62e015d000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f62dff59000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f62dfd3c000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f62dfb33000)
    libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007f62df90e000)`
    libgtk-3.so.0 => /usr/lib/x86_64-linux-gnu/libgtk-3.so.0 (0x00007f62defdf000)
    libgdk-3.so.0 => /usr/lib/x86_64-linux-gnu/libgdk-3.so.0 (0x00007f62ded03000)
    libcairo.so.2 => /usr/lib/x86_64-linux-gnu/libcairo.so.2 (0x00007f62de9ef000)
    libgdk_pixbuf-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0 (0x00007f62de7cd000)
    libgobject-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 (0x00007f62de579000)
    `libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f62de268000)`
    libavcodec-ffmpeg.so.56 => /usr/lib/x86_64-linux-gnu/libavcodec-ffmpeg.so.56 (0x00007f62dce3e000)
    libavformat-ffmpeg.so.56 => /usr/lib/x86_64-linux-gnu/libavformat-ffmpeg.so.56 (0x00007f62dca40000)
    libavutil-ffmpeg.so.54 => /usr/lib/x86_64-linux-gnu/libavutil-ffmpeg.so.54 (0x00007f62dc7d1000)
    libswscale-ffmpeg.so.3 => /usr/lib/x86_64-linux-gnu/libswscale-ffmpeg.so.3 (0x00007f62dc542000)
    `/lib64/ld-linux-x86-64.so.2 (0x0000561e16755000)`
    libgmodule-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 (0x00007f62dc33d000)
    libpangocairo-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 (0x00007f62dc130000)
    libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f62dbdf5000)
    libXi.so.6 => /usr/lib/x86_64-linux-gnu/libXi.so.6 (0x00007f62dbbe5000)
    libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f62db9df000)
    libcairo-gobject.so.2 => /usr/lib/x86_64-linux-gnu/libcairo-gobject.so.2 (0x00007f62db7d5000)
    libatk-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libatk-1.0.so.0 (0x00007f62db5b0000)
    libatk-bridge-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libatk-bridge-2.0.so.0 (0x00007f62db381000)
    libepoxy.so.0 => /usr/lib/x86_64-linux-gnu/libepoxy.so.0 (0x00007f62db08b000)
    libpangoft2-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0 (0x00007f62dae75000)
    libpango-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 (0x00007f62dac29000)
    libfontconfig.so.1 => /usr/lib/x86_64-linux-gnu/libfontconfig.so.1 (0x00007f62da9e5000)
    libgio-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0 (0x00007f62da65d000)
    libXinerama.so.1 => /usr/lib/x86_64-linux-gnu/libXinerama.so.1 (0x00007f62da459000)
    libXrandr.so.2 => /usr/lib/x86_64-linux-gnu/libXrandr.so.2 (0x00007f62da24e000)
    libXcursor.so.1 => /usr/lib/x86_64-linux-gnu/libXcursor.so.1 (0x00007f62da044000)
    libXcomposite.so.1 => /usr/lib/x86_64-linux-gnu/libXcomposite.so.1 (0x00007f62d9e40000)
    libXdamage.so.1 => /usr/lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f62d9c3d000)
    libxkbcommon.so.0 => /usr/lib/x86_64-linux-gnu/libxkbcommon.so.0 (0x00007f62d99fe000)
    libwayland-cursor.so.0 => /usr/lib/x86_64-linux-gnu/libwayland-cursor.so.0 (0x00007f62d97f5000)
    libwayland-egl.so.1 => /usr/lib/x86_64-linux-gnu/libwayland-egl.so.1 (0x00007f62d95f3000)
    libwayland-client.so.0 => /usr/lib/x86_64-linux-gnu/libwayland-client.so.0 (0x00007f62d93e5000)
    libmirclient.so.9 => /usr/lib/x86_64-linux-gnu/libmirclient.so.9 (0x00007f62d9163000)
    libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f62d8f51000)
    libpixman-1.so.0 => /usr/lib/x86_64-linux-gnu/libpixman-1.so.0 (0x00007f62d8ca8000)
    libfreetype.so.6 => /usr/lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f62d89fe000)
    libxcb-shm.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-shm.so.0 (0x00007f62d87fa000)
    libxcb-render.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-render.so.0 (0x00007f62d85ef000)
    libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f62d83cd000)
    libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007f62d81c3000)
    libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007f62d7fba000)
    libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f62d7d4a000)
    libswresample-ffmpeg.so.1 => /usr/lib/x86_64-linux-gnu/libswresample-ffmpeg.so.1 (0x00007f62d7b2d000)
    libva.so.1 => /usr/lib/x86_64-linux-gnu/libva.so.1 (0x00007f62d7911000)
    libzvbi.so.0 => /usr/lib/x86_64-linux-gnu/libzvbi.so.0 (0x00007f62d7686000)
    libxvidcore.so.4 => /usr/lib/x86_64-linux-gnu/libxvidcore.so.4 (0x00007f62d7372000)
    libx265.so.79 => /usr/lib/x86_64-linux-gnu/libx265.so.79 (0x00007f62d6752000)
    libx264.so.148 => /usr/lib/x86_64-linux-gnu/libx264.so.148 (0x00007f62d63ae000)
    libwebp.so.5 => /usr/lib/x86_64-linux-gnu/libwebp.so.5 (0x00007f62d6152000)
    libwavpack.so.1 => /usr/lib/x86_64-linux-gnu/libwavpack.so.1 (0x00007f62d5f28000)
    libvpx.so.3 => /usr/lib/x86_64-linux-gnu/libvpx.so.3 (0x00007f62d5b04000)
    libvorbisenc.so.2 => /usr/lib/x86_64-linux-gnu/libvorbisenc.so.2 (0x00007f62d585b000)
    libvorbis.so.0 => /usr/lib/x86_64-linux-gnu/libvorbis.so.0 (0x00007f62d562e000)
    libtwolame.so.0 => /usr/lib/x86_64-linux-gnu/libtwolame.so.0 (0x00007f62d540b000)
    libtheoraenc.so.1 => /usr/lib/x86_64-linux-gnu/libtheoraenc.so.1 (0x00007f62d51cc000)
    libtheoradec.so.1 => /usr/lib/x86_64-linux-gnu/libtheoradec.so.1 (0x00007f62d4fb1000)
    libspeex.so.1 => /usr/lib/x86_64-linux-gnu/libspeex.so.1 (0x00007f62d4d98000)
    libsnappy.so.1 => /usr/lib/x86_64-linux-gnu/libsnappy.so.1 (0x00007f62d4b90000)
    libshine.so.3 => /usr/lib/x86_64-linux-gnu/libshine.so.3 (0x00007f62d4982000)
    libschroedinger-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libschroedinger-1.0.so.0 (0x00007f62d46ad000)
    libopus.so.0 => /usr/lib/x86_64-linux-gnu/libopus.so.0 (0x00007f62d4463000)
    `libopenjpeg.so.5 => /usr/lib/x86_64-linux-gnu/libopenjpeg.so.5 (0x00007f62d423f000)`
    libmp3lame.so.0 => /usr/lib/x86_64-linux-gnu/libmp3lame.so.0 (0x00007f62d3fca000)
    libgsm.so.1 => /usr/lib/x86_64-linux-gnu/libgsm.so.1 (0x00007f62d3dbc000)
    libcrystalhd.so.3 => /usr/lib/x86_64-linux-gnu/libcrystalhd.so.3 (0x00007f62d3ba0000)
    liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f62d397e000)
    libssh-gcrypt.so.4 => /usr/lib/x86_64-linux-gnu/libssh-gcrypt.so.4 (0x00007f62d3734000)
    librtmp.so.1 => /usr/lib/x86_64-linux-gnu/librtmp.so.1 (0x00007f62d3518000)
    libmodplug.so.1 => /usr/lib/x86_64-linux-gnu/libmodplug.so.1 (0x00007f62d318d000)
    libgme.so.0 => /usr/lib/x86_64-linux-gnu/libgme.so.0 (0x00007f62d2f3e000)
    libbluray.so.1 => /usr/lib/x86_64-linux-gnu/libbluray.so.1 (0x00007f62d2cf5000)
    libgnutls.so.30 => /usr/lib/x86_64-linux-gnu/libgnutls.so.30 (0x00007f62d29c5000)
    libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f62d27b4000)
    libatspi.so.0 => /usr/lib/x86_64-linux-gnu/libatspi.so.0 (0x00007f62d2585000)
    libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007f62d2338000)
    libharfbuzz.so.0 => /usr/lib/x86_64-linux-gnu/libharfbuzz.so.0 (0x00007f62d20da000)
    libthai.so.0 => /usr/lib/x86_64-linux-gnu/libthai.so.0 (0x00007f62d1ed0000)
    libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f62d1ca7000)
    libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f62d1a85000)
    libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007f62d186a000)
    libmircommon.so.5 => /usr/lib/x86_64-linux-gnu/libmircommon.so.5 (0x00007f62d1638000)
    libmirprotobuf.so.3 => /usr/lib/x86_64-linux-gnu/libmirprotobuf.so.3 (0x00007f62d13d7000)
    libboost_system.so.1.58.0 => /usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0 (0x00007f62d11d2000)
    libprotobuf-lite.so.9 => /usr/lib/x86_64-linux-gnu/libprotobuf-lite.so.9 (0x00007f62d0fa1000)
    libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f62d0d9c000)
    libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f62d0b96000)
    libsoxr.so.0 => /usr/lib/x86_64-linux-gnu/libsoxr.so.0 (0x00007f62d0931000)
    libnuma.so.1 => /usr/lib/x86_64-linux-gnu/libnuma.so.1 (0x00007f62d0725000)
    libogg.so.0 => /usr/lib/x86_64-linux-gnu/libogg.so.0 (0x00007f62d051c000)
    liborc-0.4.so.0 => /usr/lib/x86_64-linux-gnu/liborc-0.4.so.0 (0x00007f62d029b000)
    libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20 (0x00007f62cffba000)
    libgssapi_krb5.so.2 => /usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2 (0x00007f62cfd6f000)
    libhogweed.so.4 => /usr/lib/x86_64-linux-gnu/libhogweed.so.4 (0x00007f62cfb3c000)
    libnettle.so.6 => /usr/lib/x86_64-linux-gnu/libnettle.so.6 (0x00007f62cf906000)
    libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007f62cf685000)
   `libxml2.so.2 => /usr/local/lib/libxml2.so.2 (0x00007f62cf31e000)`
    libp11-kit.so.0 => /usr/lib/x86_64-linux-gnu/libp11-kit.so.0 (0x00007f62cf0b8000)
    libidn.so.11 => /usr/lib/x86_64-linux-gnu/libidn.so.11 (0x00007f62cee85000)
    libtasn1.so.6 => /usr/lib/x86_64-linux-gnu/libtasn1.so.6 (0x00007f62cec72000)
    libsystemd.so.0 => /lib/x86_64-linux-gnu/libsystemd.so.0 (0x00007f62cebec000)
    libgraphite2.so.3 => /usr/lib/x86_64-linux-gnu/libgraphite2.so.3 (0x00007f62ce9c7000)
    libdatrie.so.1 => /usr/lib/x86_64-linux-gnu/libdatrie.so.1 (0x00007f62ce7bf000)
    libboost_filesystem.so.1.58.0 => /usr/lib/x86_64-linux-gnu/libboost_filesystem.so.1.58.0 (0x00007f62ce5a6000)
    libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007f62ce384000)
    libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007f62ce16f000)
    libkrb5.so.3 => /usr/lib/x86_64-linux-gnu/libkrb5.so.3 (0x00007f62cde9d000)
    libk5crypto.so.3 => /usr/lib/x86_64-linux-gnu/libk5crypto.so.3 (0x00007f62cdc6e000)
    libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007f62cda69000)
    libkrb5support.so.0 => /usr/lib/x86_64-linux-gnu/libkrb5support.so.0 (0x00007f62cd85e000)
    libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007f62cd659000)

可以看出在Ubuntu跑这个程序需要这么多动态链接库的支持,我们在开发板上有好多是用不到的,其中一部分在交叉编译安装opencv时已经禁用掉了
我把我认为比较重要的库都标注成了绿色。(只是我个人理解,水平有限。)
文章:http://ebaina.com/bbs/forum.php?mod=viewthread&tid=7828&page=1&extra=#pid16931 上面说:

解决方法:
1.对于grfmt_png.cpp的各种undefined reference to,原因是交叉编译环境缺少libpng,解决办法是下载libpng,然后进行交叉编译,编译后生成include和lib文件夹,分别把include和lib下的文件拷贝到交叉编译环境的include和lib文件下,我的也就是上面的/usr/local/hi-arm/arm-hisiv100-linux/arm-hisiv100-linux-uclibcgnueabi/include/和/usr/local/hi-arm/arm-hisiv100-linux/arm-hisiv100-linux-uclibcgnueabi/lib/
然后再进行编译,记得编译命令上加上-lpng,然后发现grfmt_png.cpp的错误都没有了。
2.对于grfmt_jpeg.cpp的各种undefined reference to,是交叉编译环境缺少了libjpeg,解决办法参考上面的1,下载libjpeg,交叉编译,拷贝include和lib文件到交叉编译环境的include和lib下,编译加上-ljpeg
3对于persistence.cpp的各种undefined reference to,是交叉编译环境缺少了libxml2,解决办法同上,编译时加上-xlm2后,这个错误就没了。

受到这个启发,我决定试试。
于是我打算重新交叉编译安装opencv3.1.0和支持xml,jpeg,png的库。
编译libxml2参考:
http://blog.csdn.net/lanyou1900/article/details/47782067

安装libiconv:
http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.13.1.tar.gz

./configure CC=arm-none-linux-gnueabi-gcc --host=arm-none-linux-gnueabi --prefix=/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libiconv //(这个文件夹自己建立的)
make
make install 

安装libz:

./configure --prefix=/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libz
`修改makefile:将30行左右改为:(将LDSHARED 改为交叉编译器)
LDSHARED=arm-none-linux-gnueabi-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map`
`要不然会出现错误:/usr/bin/ld: adler32.lo:普通ELF重定位(M: 40)
/usr/bin/ld: adler32.lo:普通ELF重定位(M: 40)
adler32.lo: 无法添加符号: 文件格式错误
collect2: error: ld returned 1 exit status
Makefile:163: recipe for target 'libz.so.1.2.8' failed`
make CC=arm-none-linux-gnueabi-gcc LD=arm-none-linux-gnueabi-ld AR=arm-none-linux-gnueabi-ar
make install

安装libxml2:

./configure --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc AR=arm-none-linux-gnueabi-ar LD=arm-none-linux-gnueabi-ld ANLIB=arm-none-linux-gnueabi-ranlib --prefix=/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libxml2 --with-zlib=/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libz  --with-iconv=/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libiconv
make
`出现错误:parserInternals.c:36:18: fatal error: zlib.h: No such file or directory
compilation terminated.
Makefile:1248: recipe for target 'parserInternals.lo' failed
make[2]: *** [parserInternals.lo] Error 1
make[2]: Leaving directory '/home/ds/build/xml/libxml2-2.9.4'
Makefile:1440: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/ds/build/xml/libxml2-2.9.4'
Makefile:859: recipe for target 'all' failed
make: *** [all] Error 2
于是我去makefile文件,搜索libiconv,在对应的位置把libz的动态链接库和位置和头文件都添加上
XML_INCLUDEDIR = -I${includedir}/libxml2 -I/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libiconv/include -I/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libz/include
XML_LIBS = -lxml2 -lz   -L/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libiconv/lib -liconv  -lm -L/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libz/lib -lz
CPPFLAGS =  -I/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libiconv/include -I/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libz/include
ICONV_LIBS = -L/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libiconv/lib -liconv -L/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libz/lib -lz

这个错误解决。又出现下面python错误,不过网上说没关系,我暂时忽略了。我看了以下makefile文件,应该是编译时python指定的路径不对,或者缺少库。如果不成功再回来解决。
`

make install

出现错误:

cc1: warning: include location "/usr/include/python2.7" is unsafe for cross-compilation [-Wpoison-system-directories]
In file included from /usr/include/python2.7/Python.h:8:0,
                 from libxml.c:14:
/usr/include/python2.7/pyconfig.h:30:52: fatal error: arm-linux-gnueabi/python2.7/pyconfig.h: No such file or directory
compilation terminated.
Makefile:623: recipe for target 'libxml.lo' failed
make[4]: *** [libxml.lo] Error 1
make[4]: Leaving directory '/home/ds/build/xml/libxml2-2.9.4/python'
Makefile:684: recipe for target 'install-recursive' failed
make[3]: *** [install-recursive] Error 1
make[3]: Leaving directory '/home/ds/build/xml/libxml2-2.9.4/python'
Makefile:841: recipe for target 'install' failed
make[2]: *** [install] Error 2
make[2]: Leaving directory '/home/ds/build/xml/libxml2-2.9.4/python'
Makefile:1440: recipe for target 'install-recursive' failed
make[1]: *** [install-recursive] Error 1
make[1]: Leaving directory '/home/ds/build/xml/libxml2-2.9.4'
Makefile:1743: recipe for target 'install' failed
make: *** [install] Error 2

网上说是python错误无视即可。http://www.aichengxu.com/view/40322
用链接里例子测试了下,成功生成了可执行文件(不过我没移植到板子上测试,等全部的库弄完了再单独测试这个)。

#include 
#include 
#include 
int main(int argc, char **argv)
{
    xmlDocPtr doc = NULL;
    xmlNodePtr root_node = NULL, node = NULL, node1 = NULL;
    doc = xmlNewDoc(BAD_CAST "1.0");
    root_node = xmlNewNode(NULL, BAD_CAST "root");
    xmlDocSetRootElement(doc, root_node);
    xmlNewChild(root_node, NULL, BAD_CAST "node1",BAD_CAST "content of node1");
    node=xmlNewChild(root_node, NULL, BAD_CAST "node3",BAD_CAST"node has attributes");
    xmlNewProp(node, BAD_CAST "attribute", BAD_CAST "yes");
    node = xmlNewNode(NULL, BAD_CAST "node4");
    node1 = xmlNewText(BAD_CAST"other way to create content");
    xmlAddChild(node, node1);
    xmlAddChild(root_node, node);
    xmlSaveFormatFileEnc(argc > 1 ? argv[1] : "-", doc, "UTF-8", 1);
    xmlFreeDoc(doc);
    xmlCleanupParser();
    xmlMemoryDump();  
    return 0;
}
arm-none-linux-gnueabi-gcc -I/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libxml2/include/libxml2 -I/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libz/include -I/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libiconv/include  -L/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libxml2/lib -L/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libz/lib -L/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libiconv/lib -lz -liconv -lxml2 xml2test.c -o test  //因为libxml2依赖那两个库,因此要加上,否则出错。

接下来安装:libjpeg
http://www.ijg.org/

./configure --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc  --prefix=/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libjpeg
make
make install

安装libpng:
https://sourceforge.net/projects/libpng/files/
或者http://download.csdn.net/download/damys/9326857

./configure --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc  --prefix=/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libpng --with-zlib=/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libz/

出错:

checking for zlibVersion in -lz... no
checking for /home/ds/arm-2013.05/x86_64-linux-gnu/usr/libz/zlibVersion in -lz... no
configure: error: zlib not installed

于是加上zlib库具体的位置

./configure --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc  --prefix=/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libpng LIBS=-L/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libz/lib CPPFLAGS=-I/home/ds/arm-2013.05/x86_64-linux-gnu/usr/libz/include
make
make install

成功。

编译时可以加上以下参数:

如果你要编译一个库的源代码,可以把它编译成静态库,也可以把它编译成动态库。如果你想编译成动态库,就用 --enable-shared参数;如果你想编译成静态库,就用--enable-static参数。

交叉编译 x264,xvid,ffmpeg
为了使OpenCV能处理视频,我们要事先交叉编译ffmpeg,而ffmpeg又是依赖x264和xvid的。
安装yasm(x264需要用到的汇编编译器):
http://yasm.tortall.net/Download.html

./configure --host=arm-none-linux-gnueabi CC=arm-none-linux-gnueabi-gcc  --prefix=/home/ds/arm-2013.05/x86_64-linux-gnu/usr/yasm
make

交叉编译x264

CC=arm-none-linux-gnueabi-gcc ./configure --host=arm-none-linux-gnueabi --disable-asm  --prefix=/home/ds/arm-2013.05/x86_64-linux-gnu/usr/x264
make
make install

交叉编译libxvid:


猜测三:xml编码问题

用UltraEdit把编码都改为UNIX utf-8 ,发现还是出现相同错误。(后来发现从ubuntu拷贝到板子上本身编码是没问题的。)
查看opencv3.1源码,persistance.cpp —>

static void
icvXMLParse( CvFileStorage* fs )
{
    char* ptr = fs->buffer_start;
    CvStringHashNode *key = 0, *key2 = 0;
    CvAttrList* list = 0;
    int tag_type = 0;

    // CV_XML_INSIDE_TAG is used to prohibit leading comments
    ptr = icvXMLSkipSpaces( fs, ptr, CV_XML_INSIDE_TAG );

    if( memcmp( ptr, ", 5 ) != 0 ) //比较前5个字节,因为编码格式是8位。每个字符占8位。
        CV_PARSE_ERROR( "Valid XML should start with \'\'" );

    ptr = icvXMLParseTag( fs, ptr, &key, &list, &tag_type );

     /*{
        const char* version = cvAttrValue( list, "version" );
        if( version && strncmp( version, "1.", 2 ) != 0 )
           CV_Error( CV_StsParseError, "Unsupported version of XML" );
    }*/    
    // we support any 8-bit encoding, so we do not need to check the actual encoding.//支持任何8位的编码
    // we do not support utf-16, but in the case of utf-16 we will not get here anyway.
    /*{
        const char* encoding = cvAttrValue( list, "encoding" );
        if( encoding && strcmp( encoding, "ASCII" ) != 0 &&
            strcmp( encoding, "UTF-8" ) != 0 &&
            strcmp( encoding, "utf-8" ) != 0 )
            CV_PARSE_ERROR( "Unsupported encoding" );
    }*/

    while( *ptr != '\0' )
    {
        ptr = icvXMLSkipSpaces( fs, ptr, 0 );

        if( *ptr != '\0' )
        {
            CvFileNode* root_node;
            ptr = icvXMLParseTag( fs, ptr, &key, &list, &tag_type );
            if( tag_type != CV_XML_OPENING_TAG ||
                strcmp(key->str.ptr,"opencv_storage") != 0 )
                CV_PARSE_ERROR( " tag is missing" );

            root_node = (CvFileNode*)cvSeqPush( fs->roots, 0 );
            ptr = icvXMLParseValue( fs, ptr, root_node, CV_NODE_NONE );
            ptr = icvXMLParseTag( fs, ptr, &key2, &list, &tag_type );
            if( tag_type != CV_XML_CLOSING_TAG || key != key2 )
                CV_PARSE_ERROR( " tag is missing" );
            ptr = icvXMLSkipSpaces( fs, ptr, 0 );
        }
    }

    assert( fs->dummy_eof != 0 );
}
/** @overload
    @param source Name of the file to open or the text string to read the data from. Extension of the
    file (.xml or .yml/.yaml) determines its format (XML or YAML respectively). Also you can append .gz
    to work with compressed files, for example myHugeMatrix.xml.gz. If both FileStorage::WRITE and
    FileStorage::MEMORY flags are specified, source is used just to specify the output file format (e.g.
    mydata.xml, .yml etc.).
    @param flags Mode of operation. See  FileStorage::Mode
    @param encoding Encoding of the file. Note that UTF-16 XML encoding is not supported currently and
    you should use 8-bit encoding instead of it.
    */
    CV_WRAP FileStorage(const String& source, int flags, const String& encoding=String());

    /** @overload */
    FileStorage(CvFileStorage* fs, bool owning=true);

可以看出任何8位的字符编码,opencv都是支持的。因此排除字符编码因素。


猜测四:是xml文件过大出现问题

在网上找简单的xml读写例子:

//readxml.cpp
#include   
#include   
#include "opencv2/opencv.hpp"  

using namespace std;  
using namespace cv;

int main(int argc, char* argv[])  
{  
    //创建XML文件存储  
    CvFileStorage* fs = cvOpenFileStorage("jarvischu.xml",  
                           0,     //用于存储的内存,如果为NULL,则会使用一个临时内存  
                           CV_STORAGE_WRITE,  
                          "utf-8"//编码  
                          );  
    //写入数据  

    cvWriteInt(fs,"frame_count",10);  //--写Int  
    cvWriteReal(fs,"pi",3.14);             //--写Float  

    //--写结构体  
    cvStartWriteStruct(fs,"frame_size",CV_NODE_MAP,"id_size" );// 有名称(会新建一个标签)  
    cvWriteInt(fs,"width",320);  
    cvWriteInt(fs,"height",200);  
    cvEndWriteStruct(fs);  

    cvStartWriteStruct(fs,"author_info",CV_NODE_SEQ,"id_author");// 无名称  
    cvWriteString(fs,0,"JarvisChu");  
    cvWriteString(fs,0,"China");  
    cvEndWriteStruct(fs);  

    //--写矩阵  
    unsigned char vec[]={1,2,3,4,5,6,7,8,9};  
    CvMat mat = cvMat(3,3,CV_8UC1,vec);  
    cvWrite(fs,"Matrix",&mat);  

    //--写注释  
    cvWriteComment(fs,"This is a example for operatoring the xml file",0);//不为0表示放在当前行,0表示新行  

    //释放  
    cvReleaseFileStorage(&fs);  

    //打开XML文件  
    fs = cvOpenFileStorage("jarvischu.xml",  
                    0,     //用于存储的内存,如果为NULL,则会使用一个临时内存  
                CV_STORAGE_READ,  
                "GB2312"//编码  GB2312
                   );  

    //读取数据  
    int f = cvReadIntByName(fs,0,"frame_count",0);//读取有名字的Int  

    //--读取元素数据  
    CvFileNode* fn = cvGetFileNodeByName(fs,0,"frame_size"); //先读取父元素(标签,节点)  
    int width = cvReadIntByName(fs,fn,"width"); //通过父元素读取子元素  
    int height = cvReadIntByName(fs,fn,"height");  

    //--读取元素内的顺序数据  
    fn = cvGetFileNodeByName(fs,0,"author_info");//先读取元素  
    CvSeq* seq = fn->data.seq;            //获取元素的顺序流  
    const char* name = cvReadString((CvFileNode*)cvGetSeqElem(seq,0));//读取顺序流中数据 0  
    const char* country = cvReadString((CvFileNode*)cvGetSeqElem(seq,1));//读取顺序流中数据 1  

    cout<<"frame_count:"<"width:"<"height"<cout <<"name:"<"country:"<return 0;  
} 

和读写yml的例子:

readyml.cpp
#include 
#include "opencv2/opencv.hpp"
#include "opencv2/ml.hpp"
#include 
#include 
using namespace cv;
using namespace std;
int main(int argc, char **argv)  
    {  
/*
    FileStorage fs("test.yml", FileStorage::WRITE);
    fs << "frameCount" << 5;
    time_t rawtime; time(&rawtime);
    fs << "calibrationDate" << asctime(localtime(&rawtime));
    Mat cameraMatrix = (Mat_(3,3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1); //又一种Mat初始化方式
    Mat distCoeffs = (Mat_(5,1) << 0.1, 0.01, -0.001, 0, 0);
    fs << "cameraMatrix" << cameraMatrix << "distCoeffs" << distCoeffs;

    //features为一个大小为3的向量,其中每个元素由随机数x,y和大小为8的uchar数组组成
    fs << "features" << "[";
    for( int i = 0; i < 3; i++ )
    {
        int x = rand() % 640;
        int y = rand() % 480;
        uchar lbp = rand() % 256;
        fs << "{:" << "x" << x << "y" << y << "lbp" << "[:";
        for( int j = 0; j < 8; j++ )
            fs << ((lbp >> j) & 1);
        fs << "]" << "}";
    }
    fs << "]";
    fs.release();*/


    FileStorage fs("test.yml", FileStorage::READ);

    //方式一: []操作符
    int frameCount = (int)fs["frameCount"];

    //方式二: FileNode::operator >>()
    string date;
    fs["calibrationDate"] >> date;

    Mat cameraMatrix2, distCoeffs2;
    fs["cameraMatrix"] >> cameraMatrix2;
    fs["distCoeffs"] >> distCoeffs2;

    //注意FileNodeIterator的使用,似乎只能用一维数组去读取里面所有的数据
    FileNode features = fs["features"];
    FileNodeIterator it = features.begin(), it_end = features.end();
    int idx = 0;
    std::vector lbpval;
    for( ; it != it_end; ++it, idx++ )
    {
        cout << "feature #" << idx << ": ";
        cout << "x=" << (int)(*it)["x"] << ", y=" << (int)(*it)["y"] << ", lbp: (";
        (*it)["lbp"] >> lbpval;  //直接读出一维向量

        for( int i = 0; i < (int)lbpval.size(); i++ )
            cout << " " << (int)lbpval[i];
        cout << ")" << endl;
    }
    fs.release();
return 0;
    } 

重点内容结果:在arm上写xml并保存成功,但是读取时出现相同错误。排除这一猜测。
但是在arm 上读写保存yml文件都成功。

猜测五:xml路径或者opencv中的load加载问题

  FILE* f=fopen(kDefaultAnnPath, "rb+");//http://baike.baidu.com/link?url=1AGB1MzmqkrH0iMjhCb2KTxGIp8u5rb7zebfMGl7gKma5uIcbEUwIsxvqyuo27cA1kzO6yYbKhl-dxNV7ZuBYa
      fseek(f, 0, SEEK_END);//函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere(偏移起始位置:文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件尾2(SEEK_END))为基准,偏移offset(指针偏移量)个字节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。(让stream指针指向文件尾)
      long l = ftell(f);//函数 ftell 用于得到文件位置指针当前位置相对于文件首的偏移字节数。在随机方式存取文件时,由于文件位置频繁的前后移动,程序不容易确定文件的当前位置。(为了得到文件的字节数)
      fseek(f, 0, SEEK_SET);//让stream指针指向文件头,int fseek(FILE *stream, long offset, int fromwhere);
      char * str =new char[1024*1024];
      fread(str, l, 1, f);//函数原型size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;参 数: buffer用于接收数据的内存地址;size : 要读的每个数据项的字节数,单位是字节; count: 要读count个数据项,每个数据项size个字节;stream:输入流
      fclose(f);
      str[l] = '\0';//把str最后一个字符设置成,字符串结束符
      ann_=ml::ANN_MLP::loadFromString(str);

还是报相同错误。排除。


猜测六:是opencv版本问题

根据以上的结果基本可以断定原因是:在opencv读xml文件的方式在PC(Ubuntu)上和在arm 中的linux上是不同的。
因此我要交叉编译opencv2.4.9,并且用他的库编译一个读写xml文件的程序,移植到板子上是否有问题。
用上面那个readxml.cpp的例子,用opencv-2.4.9的库交叉编译出来放到板子上跑,还是写xml和保存没问题但是读的时候还是相同的错误。排除。


猜测七:是交叉编译器的问题

开发板从SD卡启动,我查看内核版本:

ds@ds-Lenovo:~/build/filesys_zedboard/备份$ file uImage 
uImage: u-boot legacy uImage, Linux-4.0.0-xilinx, Linux/ARM, OS Kernel Image (Not compressed), 3562248 bytes, Mon Mar 28 05:19:08 2016, Load Address: 0x00008000, Entry Point: 0x00008000, Header CRC: 0x94BFB3BC, Data CRC: 0x72900298

我之前安装交叉编译器之前未安装32位库,不知道这个有没有影响。
重新安装交叉编译器,之前用的是从网上下载的arm-2013.05-24-arm-none-linux-gnueabi-x86_64-linux-gnu.tar.bz2。
现在用xilinx-2011.09-50-arm-xilinx-linux-gnueabi.bin,进行交叉编译readxml.cpp
。移植到zedboard上,还是相同的错误。(也有可能是交叉编译器版本太低,以后用高版本的试一下)

猜测八:是交叉编译opencv时出问题了。

于是打算重新交叉编译opencv3.1.0。
我按照
http://www.eefocus.com/beiyangguangdian/blog/14-03/302119_52e49.html 的方法移植的,可是老是出现交叉编译器include中c++头文件math.h或者cmath的问题。找了网上说什么的都有,有说是交叉编译器版本应该用新版本,有的说是ffmpeg版本的问题。
我分别用opencv3.1版本和opencv2.4.9版本都试了,如果只加上with_jpeg,png,tiff,v4l不出错,一旦加上就出上边math.h或者cmath里面的错误❌。暂时没有解决。
不过xml这个问题,我觉得应该是交叉编译器或者opencv版本或者编译时依赖库的问题(不知道和ubuntu是64位的有没有关系),以后这个问题解决了,我再回过头来记录一下。


现在阶段我用了XAPP1167里面的demo,里面有现成的opencv_install/arm_linux ,有编译好的opencv库,而且支持ffmpeg。它的opencv是2.4.5版本的。
我用它提供的库交叉编译了opencv自带的人脸识别程序和自己的xml读写程序都成功了。(交叉编译器是arm-2014.05-28-arm-none-eabi-i686版本的,其实我觉得和交叉编译器没关系,这里只是记录一下)

你可能感兴趣的:(linux,opencv)