系统:Ubuntu 18.04.1 LTS amd64
编译工具链: arm-linux-gcc version 7.3.1
一、 准备工作:
下载QT 5.12带集成开发环境(QT Creator)的可执行文件:
下载QT5.12源码:
下载opencv4.0.0源码:
下载交叉编译工具链7.3.1:
https://releases.linaro.org/components/toolchain/binaries/latest-7/arm-linux-gnueabi/
选择gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabi.tar.xz
二、 安装QT Creator和PC版QT 5.12
在work目录下进入QT5.12文件夹,运行.run文件:
需要更改权限,不然不能运行。
然后弹出图形化安装界面:
Next->Skip->Next:
选择自己的路径:
勾选所有
Next
同意协议
Install
安装完成。
Next
Finish。
创建一个带窗体的工程hello试试看是否成功:
成功。
三、 编译PC端opencv4.0.0
进入opencv文件夹解压opencv4.0.0源码,直接右击解压:
进入源码目录创建build_x86_64文件夹并进入:
安装cmake-gui:
sudo apt-get install cmake-qt-gui
执行cmake-gui进入配置界面并填写如下:
点击configure 选择第一项 点击finish。
过程会自动下载一些缺少的库,需要等待一段时间。
修改CMAKE_INSTALL_PREFIX为/usr/local/opencv_4.0.0
修改CMAKE_BUILD_TYPE为Release
取消WITH_TIFF
点击generate生成Makefile
退出cmake-gui
在终端make –j4等待make完成。
sudo make install安装到刚才指定的位置:
配置opencv环境:
sudo gedit /etc/ld.so.conf
加入一行:
sudo ldconfig
在QT creator中打开刚才创建的hello QT工程,配置工程如下:
Mainwindow.cpp 内容如下:
点击运行:
证明一切正常,至此PC版的opencv配置完成。
四、 安装新版的交叉编译工具链v7.3.1
在安装这个之前请从PATH中移除了旧版本的工具链路径:
解压下载的预编译好的工具链包,直接右击解压并将解压后的文件夹移动到/usr/local/arm下:
设置新工具链的环境变量写到.bashrc文件中:
sudo gedit ~/.bashrc
在文件最后添加:
保存退出。
source ~/.bashrc
输出PATH看看:
命令测试:
建立软连接通过一个脚本完成:
Cd /usr/local/arm/arm-linux-gcc-7.3.1/bin
Sudo gedit link.sh
填入内容:
执行脚本:
Sudo chmod 777 link.sh
./link.sh
建立的软连接如下图所示:
查看版本:
成功。
五、 交叉编译QT5.12
进入QT源码目录并解压,直接右击解压:
进入源码目录编辑文件/qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf
加入这些:
configure:
./configure -prefix /usr/local/arm/QT5.12.0/ -release -opensource -make libs -xplatform linux-arm-gnueabi-g++ -optimized-qmake -pch -qt-libjpeg -qt-zlib -no-opengl -skip qt3d -skip qtcanvas3d -skip qtpurchasing -no-sse2 -no-openssl -no-cups -no-glib -no-iconv -nomake examples -nomake tools -skip qtvirtualkeyboard
make –j4(至少需要一个多小时)
Sudo make install
配置默认的qmake,打开/usr/lib/x86_64-linux-gnu/qt-default/qtchooser/default.conf,将内容修改为:
qmake –v
安装完成。
六、 交叉编译opencv_4.0.0
进入opencv4.0.0源码目录并创建build_arm文件夹:
cmake-gui打开配置界面
配置如下:
点击configure
选择最后一项 Specify options for cross-compiling
并填入选择自己编译器路径。
Finish
等待生成configure。
修改CMAKE_INSTALL_PREFIX 为 /usr/local/arm/opencv_4.0.0(自己创建这个文件夹)
修改CMAKE_BUILD_TYPE 为 Release
取消BUILD_PROTOBUF、BUILD_OPENEXR、BUILD_TIFF、BUILD_ZLIB、WITH_TIFF、WITH_CUFFT、WITH_OPENCL、WITH_OPENCLAMDFFT、WITH_OPENCL_SVM、WITH_OPENCLAMDBLAS。
打开CMakeCache.txt 修改CMAKE_EXE_LINKER_FLAGS:STRING =
为
CMAKE_EXE_LINKER_FLAGS:STRING = -lpthread –lrt –ldl
保存。
点击generate生成makefile
关闭cmake-gui
make –j4
编译成功。
如果过程中抱错:#error: “No suitable threading library available”
打开3rdparty/protobuf/src/google/stubs/common.cc文件修改52行为:
去掉#include
sudo make install 安装到指定位置
至此,opencv4.0.0交叉编译完成。
七、 网络挂载文件系统:
将上篇制作的文件系统拷贝到work下:
配置nfs server:
打开/etc/exports 设置如下:
重启nfs-server:
重启开发板设置bootargs:
reset:
启动成功。
在文件系统中新建一个文件夹yjp并进入:
之前装好的工具链没有测试过能不能正常使用,这里写个helloworld测试一下:
因为是通过网络挂载的,所以这里增加的内容都会在同步到开发板的文件系统里,在板子上执行程序:
看到可以正常执行,所以工具链没问题。删掉测试文件hello hello.c hello.o
八、 交叉编译的QT库移植:
这里使用的文件系统是自做的(使用新版的工具链arm-linux-gcc7.3.1+busybox1.29.3制作的,制作过程省略,和上篇博客一样),所以它是纯净版的,里面什么库都没有,为了运行QT先把QT库拷贝到板子上,进入rootfs目录并执行:
然后打开rootfs下的etc/init.d/rcS,设置内容为:
然后在etc下新建文件mdev.conf设置内容为:
(就是直接将友善的对应目录下的mdev.conf拷贝过来)
打开etc/profile文件,增加内容:
然后在电脑端新建一个工程,拖一个按钮,拷贝一份源码到yjp文件夹下:
进入目录后:
生成了可执行文件。
在板子上执行该文件:
报错,解决方案:
定位到libQt5Core.so.5文件:
再次在板子上运行:
没有字库,我们把友善的字库文件夹直接拿过来:
改一下权限:
在板子上再次运行:
同时在板子上:
九、 人脸识别:
在刚才创建的opencvTest工程中将lena.jpg和人脸检测用到haarcascade_frontalface_default.xml拷贝到工程源码目录下:
打开该工程,设置UI为:
工程配置文件为:
QT += core gui
INCLUDEPATH += /usr/local/opencv_4.0.0/include/opencv4 \
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_calib3d.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_core.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_features2d.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_flann.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_gapi.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_highgui.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_imgcodecs.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_imgproc.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_ml.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_objdetect.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_photo.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_stitching.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_video.so
LIBS += /usr/local/opencv_4.0.0/lib/libopencv_videoio.so
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = opencvTest
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
Mainwindow.cpp文件为:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "opencv2/imgproc.hpp"
#include
#include
#include "QMessageBox"
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
imgSrc=imread("lena.jpg");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_BTorigendisplay_clicked()
{
QImage img = MatToQImage(imgSrc);
ui->imglabel->clear();
ui->imglabel->setPixmap(QPixmap::fromImage(img));
}
void MainWindow::on_BTfacedection_clicked()
{
Mat image=imgSrc.clone();
QImage img =MatToQImage( DetectFace(image));
ui->imglabel->clear();
ui->imglabel->setPixmap(QPixmap::fromImage(img));
}
void MainWindow::on_BTexit_clicked()
{
this->close();
}
QImage MainWindow::MatToQImage(cv::Mat mtx)
{
switch (mtx.type()) {
case CV_8UC3:
{
QImage img((const unsigned char *)(mtx.data), mtx.cols, mtx.rows, mtx.cols * 3, QImage::Format_RGB888);
return img.rgbSwapped();
}
break;
default:
{
QImage img;
return img;
}
break;
}
}
Mat MainWindow::DetectFace(Mat image)
{
CascadeClassifier ccf; //创建分类器对象
if(!ccf.load("haarcascade_frontalface_default.xml")) //加载训练文件
{
QMessageBox::warning(this,"error","haarcascade_forontalface_default.xml load failed!");
return image;
}
vector faces; //创建一个容器保存检测出来的脸
Mat gray;
cvtColor(image,gray,CV_BGR2GRAY); //转换成灰度图,因为harr特征从灰度图中提取
equalizeHist(gray,gray); //直方图均衡行
ccf.detectMultiScale(gray,faces,1.1,3,0,Size(10,10),Size(600,600)); //检测人脸
for(vector::const_iterator iter=faces.begin();iter!=faces.end();iter++)
{
rectangle(image,*iter,Scalar(0,0,255),2,8); //画出脸部矩形
}
return image;
}
点击运行,测试功能是否正常,发现不能正常读入图像,原因是Qt Creator在编译的时候会自己创建一个build-opencvTest-Desktop_Qt_5_12_GCC_64bit-Debug,那么我们把刚才的lena.jpg和haarcascade_frontalface_default.xml放在这个文件夹下:
重新运行:
点击OrigenDisplay:
点击FaceDection:
证明源代码写的没错,接下来就应该把源码拷贝一份进行交叉编译。
十、 将人脸识别工程移植到开发板:
先把opencv4.0.0库拷贝到板子上:
改一下权限:
在profile中导入opencv lib的库:
保存退出。
把opencvTest工程拷贝一份到yjp文件夹:
改一下权限:
打开opencvTest.pro修改内容为:
QT += core gui
INCLUDEPATH += /usr/local/arm/opencv_4.0.0/include/opencv4 \
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_calib3d.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_core.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_features2d.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_flann.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_gapi.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_highgui.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_imgcodecs.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_imgproc.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_ml.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_objdetect.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_photo.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_stitching.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_video.so
LIBS += /usr/local/arm/opencv_4.0.0/lib/libopencv_videoio.so
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = opencvTest
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
保存,编译工程:
可以看到编译成功了,但是有一大堆warning,说什么库找不着,暂时忽略。
在板子上执行看看:
报错,opencv的库找不着,但是它说的是…/…/lib下没有库,这是一个相对路径,那我们把opencv的库考到这个相对路径下:
再在板子上执行:
点OrigenDisplay
点FaceDection:
点Exit:
至此全部移植成功。
但任然存在还有一些问题,程序只能在相对路径下运行,网上说跟opencv编译时有关,需要在toolchain.cmake文件中添加一行:
set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
具体没实践。