交叉编译平台:Ubuntu 16.04.5 LTS
交叉编译工具链:aarch64-himix100-linux
移植平台:Hi3559AV100
由于编译环境是在实验室的电脑中,没有root用户权限,因此所有所需的工具和库都没有使用apt-get工具安装,同时也可能存在一些已经安装好的依赖库,若在移植过程中出现找不到所需工具或相关依赖库的情况,并且本文没有提及的,请自行查阅相关资料或以类似方法安装。
解释:
1、glib是opencv的依赖库,也需要进行交叉编译,否则会在opencv交叉编译时报错
/opt/hisi-linux/x86-arm/aarch64-himix100-linux/host_bin/../lib/gcc/aarch64-linux-gnu/6.3.0/../../../../aarch64-linux-gnu/bin/ld: cannot find -lgthread-2.0
/opt/hisi-linux/x86-arm/aarch64-himix100-linux/host_bin/../lib/gcc/aarch64-linux-gnu/6.3.0/../../../../aarch64-linux-gnu/bin/ld: cannot find -lglib-2.0
2、ffi是glib中gobject的依赖库
3、zlib是glib中gio的依赖库
确保系统中已经安装了相应的交叉编译链,直接在shell中输出交叉编译链的名称查看是否自动补全
若未安装请自行查看相关手册安装对应的交叉编译链
# 解压源码包
tar -xvf libffi-3.2.1.tar.gz
cd libffi-3.2.1
#创建输出文件夹
mkdir output
#设置交叉编译工具链
CC=aarch64-himix100-linux-gcc
#执行./configure生成Makefile, prefix是输出目录,注意改成自己的
./configure prefix=/home/sdc/yuwy/opencv/libffi-3.2.1/output --host=aarch64-himix100-linux
make
make install
#生成的so文件在output/lib64里
#解压缩
tar -xvf zlib-1.2.11.tar.gz
cd zlib-1.2.11
mkdir output
#执行./configure命令生成Makefile,注意将prefix目录替换成自己的输出目录
CC=aarch64-himix100-linux-gcc
./configure --prefix=/home/sdc/yuwy/opencv/zlib-1.2.11/output
make
make install
回到根目录解压缩glib源码包
tar -xvf glib-2.47.3.tar.gz
cd glib-2.47.3
mkdir output
之后需要新建一个配置文件
vim glib.cache
写入
glib_cv_long_long_format=ll
glib_cv_stack_grows=no
glib_cv_have_strlcpy=no
glib_cv_have_qsort_r=yes
glib_cv_va_val_copy=yes
glib_cv_uscore=no
glib_cv_rtldglobal_broken=no
ac_cv_func_posix_getpwuid_r=yes
ac_cv_func_posix_getgrgid_r=yes
执行./configure命令生成Makefile,注意将prefix目录替换成自己的输出目录
CC=aarch64-himix100-linux-gcc
./configure --prefix=/home/sdc/yuwy/opencv/glib-2.47.3/output --host=aarch64-himix100-linux --cache-file=glib.cache
接下来需要修改三个Makefile,注意对于libffi的添加一定要使用**-Wl,-rpath-link -wl,/…**,否则会无法找到库,在错误中也有提示。
#vim gobject/Makefile
LDFLAGS = -Wl,-rpath-link -Wl,/home/sdc/yuwy/opencv/libffi-3.2.1/output/lib64
#vim tests/gobject/Makefile
LDFLAGS = -Wl,-rpath-link -Wl,/home/sdc/yuwy/opencv/libffi-3.2.1/output/lib64
#vim gio/Makefile
ZLIB_CFLAGS = -I/home/sdc/yuwy/opencv/zlib-1.2.11/output/include
ZLIB_LIBS = -L/home/sdc/yuwy/opencv/zlib-1.2.11/output/lib
LDFLAGS = -Wl,-rpath-link -Wl,/home/sdc/yuwy/opencv/zlib-1.2.11/output/lib -Wl,-rpath-link -Wl,/home/sdc/yuwy/opencv/libffi-3.2.1/output/lib64
在之后的make过程中有可能还会碰到其他的库无法链接的问题,查看对应需要的库和依赖库,进行交叉编译并在对应的Makefile里添加链接即可
gdate.c错误,添加以下patch文件,patch到glib/gdate.c文件中
--- a/glib/glib/gdate.c
+++ b/glib/glib/gdate.c
@@ -2439,6 +2439,9 @@ win32_strftime_helper (const GDate *d,
*
* Returns: number of characters written to the buffer, or 0 the buffer was too small
*/
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+
gsize
g_date_strftime (gchar *s,
gsize slen,
@@ -2549,3 +2552,5 @@ g_date_strftime (gchar *s,
return retval;
#endif
}
+
+#pragma GCC diagnostic pop
patch glib/gdate.c ../001-gli b-gdate-suppress-string-format-literal-warning.patch
make
make install
unzip 3.2.0.zip -d opencv
cd opencv3.2.0
mkdir output
mkdir build
cd build
执行cmake指令
cmake -DCMAKE_BUILD_TYPE=RELEASE \
-DCMAKE_INSTALL_PREFIX=../output \
-DCMAKE_C_COMPILER=aarch64-himix100-linux-gcc \
-DCMAKE_CXX_COMPILER=aarch64-himix100-linux-g++ \
-DCMAKE_EXE_LINKER_FLAGS=-lrt -lpthread \
-DBUILD_SHARED_LIBS=ON \
-DWITH_CUDA=OFF \
-DWITH_CUFFT=OFF \
-DWITH_EIGEN=OFF \
-DWITH_FFMPEG=OFF \
-DWITH_OPENCL=OFF \
-DWITH_OPENCLAMDBLAS=OFF \
-DWITH_OPENCLAMDFFT=OFF \
-DWITH_OPENCL_SVM=OFF \
-DWITH_TIFF=OFF \
-DWITH_1394=OFF \
-DWITH_GSTREAMER=OFF \
-DWITH_JASPER=OFF \
-DWITH_LAPACK=OFF \
-DWITH_MATLAB=OFF \
-DWITH_WEBP=OFF \
-DWITH_IPP=OFF \
-DWITH_PNG=OFF \
-DBUILD_TESTS=OFF \
-DBUILD_opencv_core=ON \
-DBUILD_opencv_imgcodecs=ON \
-DBUILD_opencv_imgproc=ON \
-DZLIB_INCLUDE_DIR=/home/sdc/yuwy/opencv/opencv-3.2.0/3rdparty/zlib \
..
make
make install
一开始使用时发现设置并没有生效,后来通过查阅文档看到了note,将-D后的空格删掉之后生效,其中一些设置请自行参考官方文档按需设置
Use
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local ..
, without spaces after -D if the above example doesn’t work.
在CMakeLists.txt中添加glib库
#vim opencv-3.2.0/CMakelists.txt
link_directories(/home/sdc/yuwy/opencv/glib-2.47.3/output/lib)
无法找到 -lgthread-2.0和-lglib-2.0
aarch64-linux-gnu/bin/ld: cannot find -lgthread-2.0
aarch64-linux-gnu/bin/ld: cannot find -lglib-2.0
需要交叉编译arm版本的libglib-2.0库,见上文
编译成功后获得glib的output目录
/home/sdc/yuwy/opencv/glib-2.47.3/output/lib
在CMakeLists.txt中添加
link_directories(/home/sdc/yuwy/opencv/glib-2.47.3/output/lib)
编译完成之后就能在output中看到bin, include, lib, share四个文件夹,生成的动态库就在Lib文件夹中。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include "opencv2/highgui.hpp"
using namespace cv;
using namespace std;
#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* __cplusplus */
/******************for time mesurement*************************/
struct timeval tpstart,tpend;
unsigned long timeuses;
void timeRec()
{
gettimeofday(&tpstart,0);
}
int timeRep()
{
gettimeofday(&tpend,0);
timeuses=(tpend.tv_sec-tpstart.tv_sec)*1000000+tpend.tv_usec-tpstart.tv_usec;
printf("use time: %uus\n",timeuses);
return timeuses;
}
/********************end**************************************/
int main(int argc, char* argv[])
{
IplImage* img = NULL;
IplImage* cutImg = NULL;
CvMemStorage* storage = cvCreateMemStorage(0);
CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad("/root/haarcascade_frontalface_alt2.xml", 0, 0, 0);
CvSeq* faces;
Mat dest;
img = cvLoadImage(argv[1], 0);
timeRec();
faces = cvHaarDetectObjects(img, cascade, storage, 1.2, 2, 0, cvSize(25,25) );
timeRep();
if (faces->total == 0){
printf("no face!\n");
}
cvSetImageROI(img, *((CvRect*)cvGetSeqElem( faces, 0)));
//cvSaveImage("face.bmp", img);
dest = cvarrToMat(img);
imwrite("face.bmp", dest);
cvResetImageROI(img);
printf("face detected! in face.bmp!\n");
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
aarch64-himix100-linux-g++ \
-I/home/sdc/yuwy/opencv/opencv-3.2.0/output/include/opencv \
-I/home/sdc/yuwy/opencv/opencv-3.2.0/output/include \
-Wl,-rpath-link -Wl,/home/sdc/yuwy/opencv/glib-2.47.3/output/lib \
-L/home/sdc/yuwy/opencv/opencv-3.2.0/output/lib \
-Lhome/sdc/yuwy/opencv/opencv-3.2.0/3rdparty/lib \
-lopencv_highgui -lopencv_ml -lopencv_objdetect -lopencv_imgcodecs -lopencv_imgproc -lopencv_videoio -lopencv_core \
-lpthread -lzlib -lrt -ldl test.cpp -o test
尝试没有在编译命令中指定库,会出现找不到各种cv函数的情况,同时在手动指定库的时候,需要将opencv_core放在最后。编译完成后获得test执行文件
将需要用到的so库文件拷贝到Hi3559的lib64目录下,将test文件,一张人脸图片和使用到的haarcascade_frontalface_alt2.xml文件拷贝到root文件夹下,即可./test运行程序。
#文件路径
opencv-3.2.0/data/haarcascades_cuda/haarcascade_frontalface_alt2.xml
./test face.jpg
use time: 657048us
face detected! in face.bmp