TA的每日心情 | 慵懒 2024-5-31 23:20 |
---|
签到天数: 302 天 连续签到: 2 天 [LV.8]以坛为家I
|
本帖最后由 ky123 于 2017-10-16 09:39 编辑
楼主申请该款开发板的目标很明确,一个是舵机控制、另一个是opencv。都说arm跑opencv是个笑话,跟别人提起想法的时候总是被笑话,但不稍微试一下又怎么知道呢。于是楼主花两三天对手头各款开发板的环境配置了一下,然后挑选了三个比较常用的图像操作函数、以及本人一个项目中的算法进行测试。
至于楼主为什么唯独让香蕉派使用2.4.9版本,在另一张吐槽贴中会提到。
(一)环境搭建
关于opencv安装问题会在另一张试用贴中提到。
qt的安装这里只需要运行- sudo apt-get install qt5-default
复制代码
(二)编译过程中一些问题
问题描述一:- QtOpenCV: error while loading shared libraries: libopencv_core.so.3.2: cannot open shared object file: No such file or directory
复制代码 解决方法:
问题是由于系统不知道libopencv_core.so.3.2放在哪里,只需要在OpenCV.conf中说明就好:
在这个路径中:创建文件:在文件中写入库的安装路径(根据你编译时的路径填写,具体情况可以看我别的试用贴):启动:问题描述二:- EOF in backquote substitution
复制代码 解决方法:
这是pro文件里面有个`的字符,一开始看起来好像是屏幕的脏点,结果怎么都编译不了。
(三)编译文件搭建
本人一般是利用qt的console,方便快捷,不用搞麻烦到极点的qmake
先创建工程文件:输入代码
执行qmake修改生成的.pro文件:- QT += core
- QT -= gui
- TARGET = blur
- CONFIG += console
- CONFIG -= app_bundle
- TEMPLATE = app
- SOURCES += blur.cpp
- INCLUDEPATH += /usr/include \
- /usr/include/opencv \
- /usr/include/opencv2
- LIBS += /usr/lib/arm-linux-gnueabihf/libopencv_highgui.so \
- /usr/lib/arm-linux-gnueabihf/libopencv_core.so \
- /usr/lib/arm-linux-gnueabihf/libopencv_video.so
复制代码 其中,TARGET是生成可执行文件的文件名;
SOURCES是编译文件的文件名;
INCLUDEPATH是头文件位置,这个取决于你安装的位置,具体情况可以看我上一篇试用贴
LIBS是函数库位置,这里罗列的是一些常用的,并非全部,需要可以随时加上,这个也取决于你安装的位置,具体情况可以看我上一篇试用贴
执行编译:运行:(四)测试源码
blur滤波:- #include <iostream>
- #include <stdio.h>
- #include <time.h>
- #include <stdlib.h>
- #include "opencv2/highgui/highgui.hpp"
- #include "opencv2/imgproc/imgproc.hpp"
- using namespace cv;
- int main( )
- {
- struct timespec tpstart;
- struct timespec tpmiddle;
- struct timespec tpend;
- long timedif;
- clock_gettime(CLOCK_MONOTONIC, &tpstart);
- //【1】载入原始图
- Mat srcImage = imread("/home/qt/qt_for_opencv/28.jpg");
- //【2】测试时间
- clock_gettime(CLOCK_MONOTONIC, &tpmiddle);
- //【3】进行均值滤波操作
- Mat dstImage;
- blur( srcImage, dstImage, Size(7, 7));
- //【4】显示时间
- clock_gettime(CLOCK_MONOTONIC, &tpend);
- timedif = 1000000*(tpend.tv_sec-tpstart.tv_sec)+(tpend.tv_nsec-tpstart.tv_nsec)/1000;
- fprintf(stdout, "all took %ld microseconds\n", timedif);
- timedif = 1000000 * (tpend.tv_sec - tpmiddle.tv_sec) + (tpend.tv_nsec - tpmiddle.tv_nsec) / 1000;
- fprintf(stdout, "process took %ld microseconds\n", timedif);
- return 0;
- }
复制代码 canny算子:- #include <opencv2/opencv.hpp>
- #include<opencv2/highgui/highgui.hpp>
- #include<opencv2/imgproc/imgproc.hpp>
- using namespace cv;
- int main()
- {
- struct timespec tpstart;
- struct timespec tpmiddle;
- struct timespec tpend;
- long timedif;
- clock_gettime(CLOCK_MONOTONIC, &tpstart);
- //载入原始图
- Mat srcImage = imread("/home/qt/qt_for_opencv/28.jpg",1); //工程目录下应该有一张名为1.jpg的素材图
- Mat srcImage1 = srcImage.clone();
- clock_gettime(CLOCK_MONOTONIC, &tpmiddle);
- Mat dstImage, edge, grayImage;
- // 【1】创建与src同类型和大小的矩阵(dst)
- dstImage.create(srcImage1.size(), srcImage1.type());
- // 【2】将原图像转换为灰度图像
- cvtColor(srcImage1, grayImage, CV_BGR2GRAY);
- // 【3】先用使用 3x3内核来降噪
- blur(grayImage, edge, Size(3, 3));
- // 【4】运行Canny算子
- Canny(edge, edge, 3, 9, 3);
- //【5】将g_dstImage内的所有元素设置为0
- dstImage = Scalar::all(0);
- //【6】使用Canny算子输出的边缘图g_cannyDetectedEdges作为掩码,来将原图g_srcImage拷到目标图g_dstImage中
- srcImage1.copyTo(dstImage, edge);
- clock_gettime(CLOCK_MONOTONIC, &tpend);
- timedif = 1000000 * (tpend.tv_sec - tpstart.tv_sec) + (tpend.tv_nsec - tpstart.tv_nsec) / 1000;
- fprintf(stdout, "it took %ld microseconds\n", timedif);
- timedif = 1000000 * (tpend.tv_sec - tpmiddle.tv_sec) + (tpend.tv_nsec - tpmiddle.tv_nsec) / 1000;
- fprintf(stdout, "it took %ld microseconds\n", timedif);
- waitKey(0);
- return 0;
- }
复制代码 contours轮廓:- #include <opencv2/opencv.hpp>
- #include "opencv2/highgui/highgui.hpp"
- #include "opencv2/imgproc/imgproc.hpp"
- using namespace cv;
- using namespace std;
- int main()
- {
- struct timespec tpstart;
- struct timespec tpmiddle;
- struct timespec tpend;
- long timedif;
- clock_gettime(CLOCK_MONOTONIC, &tpstart);
- // 【1】载入原始图,且必须以二值图模式载入
- Mat srcImage = imread("/home/qt/qt_for_opencv/28.jpg", 0);
- clock_gettime(CLOCK_MONOTONIC, &tpmiddle);
- //【2】初始化结果图
- Mat dstImage = Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3);
- //【3】srcImage取大于阈值119的那部分
- srcImage = srcImage > 119;
- //【4】定义轮廓和层次结构
- vector<vector<Point> > contours;
- vector<Vec4i> hierarchy;
- //【5】查找轮廓
- //此句代码的OpenCV2版为:
- findContours( srcImage, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
- //此句代码的OpenCV3版为:
- //findContours(srcImage, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
- // 【6】遍历所有顶层的轮廓, 以随机颜色绘制出每个连接组件颜色
- int index = 0;
- for (; index >= 0; index = hierarchy[index][0])
- {
- Scalar color(rand() & 255, rand() & 255, rand() & 255);
- //此句代码的OpenCV2版为:
- drawContours( dstImage, contours, index, color, CV_FILLED, 8, hierarchy );
- //此句代码的OpenCV3版为:
- //drawContours(dstImage, contours, index, color, FILLED, 8, hierarchy);
- }
- //【7】显示最后的轮廓图
- //imshow( "轮廓图", dstImage );
- clock_gettime(CLOCK_MONOTONIC, &tpend);
- timedif = 1000000 * (tpend.tv_sec - tpstart.tv_sec) + (tpend.tv_nsec - tpstart.tv_nsec) / 1000;
- fprintf(stdout, "it took %ld microseconds\n", timedif);
- timedif = 1000000 * (tpend.tv_sec - tpmiddle.tv_sec) + (tpend.tv_nsec - tpmiddle.tv_nsec) / 1000;
- fprintf(stdout, "process took %ld microseconds\n", timedif);
- waitKey(0);
- }
复制代码 这里使用的计时是clock_gettime,可以精确到nm级别(十亿分之一秒),出于对数据读取能力差异的担忧,这里特地进行了两次测量,第一次是测总的运行时间,第二次是测单纯的图像处理时间。
(五)测试结果
一些截图:
测试平台数据:
测试结果:
这个结果也是让我有点迷糊,对于canny,竟然比512M的nano还渣?contours却稳胜了树莓派!猜测可能是由于其他都是3.3.0版本,唯独香蕉派用了2.4.9的原因。至于为什么这么做,其他的帖子会提到。以后有机会也会安装ubuntu serve编译一下3.3.0版本再进行一次测试。
|
|