爱板网论坛

查看: 193|回复: 0

[原创] 【BPI-M2 Berry试用】opencv性能小测试(vs树莓派、nanopi)

[复制链接]

11

主题

0

好友

266

积分

秀才

Rank: 3Rank: 3

  • TA的每日心情
    奋斗
    昨天 23:26
  • 签到天数: 33 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2017-10-15 21:44:34 |显示全部楼层
    本帖最后由 ky123 于 2017-10-16 09:39 编辑

    楼主申请该款开发板的目标很明确,一个是舵机控制、另一个是opencv。都说arm跑opencv是个笑话,跟别人提起想法的时候总是被笑话,但不稍微试一下又怎么知道呢。于是楼主花两三天对手头各款开发板的环境配置了一下,然后挑选了三个比较常用的图像操作函数、以及本人一个项目中的算法进行测试。
    至于楼主为什么唯独让香蕉派使用2.4.9版本,在另一张吐槽贴中会提到。

    (一)环境搭建
    关于opencv安装问题会在另一张试用贴中提到。
    qt的安装这里只需要运行
    1. sudo apt-get install qt5-default
    复制代码

    (二)编译过程中一些问题

    问题描述一:
    1. 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中说明就好:
    在这个路径中:
    1. cd /etc/ld.so.conf.d
    复制代码
    创建文件:
    1. mkdir OpenCV.conf
    复制代码
    在文件中写入库的安装路径(根据你编译时的路径填写,具体情况可以看我别的试用贴):
    1. /etc/local/lib
    复制代码
    启动:
    1. sudo ldconfig
    复制代码
    问题描述二:
    1. EOF in backquote substitution
    复制代码
    解决方法:
    这是pro文件里面有个`的字符,一开始看起来好像是屏幕的脏点,结果怎么都编译不了。


    (三)编译文件搭建
    本人一般是利用qt的console,方便快捷,不用搞麻烦到极点的qmake
    先创建工程文件:
    1. mkdir blur.cpp
    复制代码
    输入代码
    执行qmake
    1. qmake
    复制代码
    修改生成的.pro文件:
    1. QT += core
    2. QT -= gui

    3. TARGET = blur
    4. CONFIG += console
    5. CONFIG -= app_bundle

    6. TEMPLATE = app

    7. SOURCES += blur.cpp

    8. INCLUDEPATH += /usr/include \
    9. /usr/include/opencv \
    10. /usr/include/opencv2

    11. LIBS += /usr/lib/arm-linux-gnueabihf/libopencv_highgui.so \
    12. /usr/lib/arm-linux-gnueabihf/libopencv_core.so \
    13. /usr/lib/arm-linux-gnueabihf/libopencv_video.so
    复制代码
    其中,TARGET是生成可执行文件的文件名;
    SOURCES是编译文件的文件名;
    INCLUDEPATH是头文件位置,这个取决于你安装的位置,具体情况可以看我上一篇试用贴
    LIBS是函数库位置,这里罗列的是一些常用的,并非全部,需要可以随时加上,这个也取决于你安装的位置,具体情况可以看我上一篇试用贴
    执行编译:
    1. make
    复制代码
    运行:
    1. ./blur
    复制代码
    (四)测试源码
    blur滤波:
    1. #include <iostream>
    2. #include <stdio.h>
    3. #include <time.h>
    4. #include <stdlib.h>
    5. #include "opencv2/highgui/highgui.hpp"
    6. #include "opencv2/imgproc/imgproc.hpp"
    7. using namespace cv;

    8. int main( )
    9. {
    10. struct timespec tpstart;
    11. struct timespec tpmiddle;
    12. struct timespec tpend;
    13. long timedif;
    14. clock_gettime(CLOCK_MONOTONIC, &tpstart);

    15. //【1】载入原始图
    16. Mat srcImage = imread("/home/qt/qt_for_opencv/28.jpg");

    17. //【2】测试时间
    18. clock_gettime(CLOCK_MONOTONIC, &tpmiddle);

    19. //【3】进行均值滤波操作
    20. Mat dstImage;
    21. blur( srcImage, dstImage, Size(7, 7));

    22. //【4】显示时间
    23. clock_gettime(CLOCK_MONOTONIC, &tpend);
    24. timedif = 1000000*(tpend.tv_sec-tpstart.tv_sec)+(tpend.tv_nsec-tpstart.tv_nsec)/1000;
    25. fprintf(stdout, "all took %ld microseconds\n", timedif);
    26. timedif = 1000000 * (tpend.tv_sec - tpmiddle.tv_sec) + (tpend.tv_nsec - tpmiddle.tv_nsec) / 1000;
    27. fprintf(stdout, "process took %ld microseconds\n", timedif);

    28. return 0;
    29. }
    复制代码
    canny算子:
    1. #include <opencv2/opencv.hpp>
    2. #include<opencv2/highgui/highgui.hpp>
    3. #include<opencv2/imgproc/imgproc.hpp>
    4. using namespace cv;

    5. int main()
    6. {
    7.         struct timespec tpstart;
    8.         struct timespec tpmiddle;
    9.         struct timespec tpend;
    10.         long timedif;
    11.         clock_gettime(CLOCK_MONOTONIC, &tpstart);

    12.         //载入原始图
    13.         Mat srcImage = imread("/home/qt/qt_for_opencv/28.jpg",1);  //工程目录下应该有一张名为1.jpg的素材图
    14.         Mat srcImage1 = srcImage.clone();

    15.         clock_gettime(CLOCK_MONOTONIC, &tpmiddle);

    16.         Mat dstImage, edge, grayImage;

    17.         // 【1】创建与src同类型和大小的矩阵(dst)
    18.         dstImage.create(srcImage1.size(), srcImage1.type());

    19.         // 【2】将原图像转换为灰度图像
    20.         cvtColor(srcImage1, grayImage, CV_BGR2GRAY);

    21.         // 【3】先用使用 3x3内核来降噪
    22.         blur(grayImage, edge, Size(3, 3));

    23.         // 【4】运行Canny算子
    24.         Canny(edge, edge, 3, 9, 3);

    25.         //【5】将g_dstImage内的所有元素设置为0
    26.         dstImage = Scalar::all(0);

    27.         //【6】使用Canny算子输出的边缘图g_cannyDetectedEdges作为掩码,来将原图g_srcImage拷到目标图g_dstImage中
    28.         srcImage1.copyTo(dstImage, edge);

    29.         clock_gettime(CLOCK_MONOTONIC, &tpend);
    30.         timedif = 1000000 * (tpend.tv_sec - tpstart.tv_sec) + (tpend.tv_nsec - tpstart.tv_nsec) / 1000;
    31.         fprintf(stdout, "it took %ld microseconds\n", timedif);
    32.         timedif = 1000000 * (tpend.tv_sec - tpmiddle.tv_sec) + (tpend.tv_nsec - tpmiddle.tv_nsec) / 1000;
    33.         fprintf(stdout, "it took %ld microseconds\n", timedif);

    34.         waitKey(0);

    35.         return 0;
    36. }
    复制代码
    contours轮廓:
    1. #include <opencv2/opencv.hpp>
    2. #include "opencv2/highgui/highgui.hpp"
    3. #include "opencv2/imgproc/imgproc.hpp"
    4. using namespace cv;
    5. using namespace std;

    6. int main()
    7. {

    8.         struct timespec tpstart;
    9.         struct timespec tpmiddle;
    10.         struct timespec tpend;
    11.         long timedif;
    12.         clock_gettime(CLOCK_MONOTONIC, &tpstart);

    13.         // 【1】载入原始图,且必须以二值图模式载入
    14.         Mat srcImage = imread("/home/qt/qt_for_opencv/28.jpg", 0);
    15.         clock_gettime(CLOCK_MONOTONIC, &tpmiddle);

    16.         //【2】初始化结果图
    17.         Mat dstImage = Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3);

    18.         //【3】srcImage取大于阈值119的那部分
    19.         srcImage = srcImage > 119;

    20.         //【4】定义轮廓和层次结构
    21.         vector<vector<Point> > contours;
    22.         vector<Vec4i> hierarchy;

    23.         //【5】查找轮廓
    24.         //此句代码的OpenCV2版为:
    25. findContours( srcImage, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
    26.         //此句代码的OpenCV3版为:
    27. //findContours(srcImage, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);

    28.         // 【6】遍历所有顶层的轮廓, 以随机颜色绘制出每个连接组件颜色
    29.         int index = 0;
    30.         for (; index >= 0; index = hierarchy[index][0])
    31.         {
    32.                 Scalar color(rand() & 255, rand() & 255, rand() & 255);
    33.                 //此句代码的OpenCV2版为:
    34. drawContours( dstImage, contours, index, color, CV_FILLED, 8, hierarchy );
    35.                 //此句代码的OpenCV3版为:
    36. //drawContours(dstImage, contours, index, color, FILLED, 8, hierarchy);
    37.         }

    38.         //【7】显示最后的轮廓图
    39.         //imshow( "轮廓图", dstImage );

    40.         clock_gettime(CLOCK_MONOTONIC, &tpend);
    41.         timedif = 1000000 * (tpend.tv_sec - tpstart.tv_sec) + (tpend.tv_nsec - tpstart.tv_nsec) / 1000;
    42.         fprintf(stdout, "it took %ld microseconds\n", timedif);
    43.         timedif = 1000000 * (tpend.tv_sec - tpmiddle.tv_sec) + (tpend.tv_nsec - tpmiddle.tv_nsec) / 1000;
    44.         fprintf(stdout, "process took %ld microseconds\n", timedif);

    45.         waitKey(0);

    46. }
    复制代码
    这里使用的计时是clock_gettime,可以精确到nm级别(十亿分之一秒),出于对数据读取能力差异的担忧,这里特地进行了两次测量,第一次是测总的运行时间,第二次是测单纯的图像处理时间。

    (五)测试结果
    一些截图:
    S~@8S9X@MJG)U0F3OP~V@DB.jpg

    0%]@8O`ZE9_3Y[(8[HXQKRR.jpg

    JXBWCB(]N7VWNE5(A$H73K0.png

    0%]@8O`ZE9_3Y[(8[HXQKRR.jpg


    测试平台数据:
    A7TS2UZK2WKL}H6@{F9{O(8.png


    测试结果:
    0{W%FPT9I7O0`XXT[OU1G)L.png


    这个结果也是让我有点迷糊,对于canny,竟然比512M的nano还渣?contours却稳胜了树莓派!猜测可能是由于其他都是3.3.0版本,唯独香蕉派用了2.4.9的原因。至于为什么这么做,其他的帖子会提到。以后有机会也会安装ubuntu serve编译一下3.3.0版本再进行一次测试。

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /2 下一条

    手机版|爱板网 |网站地图  

    GMT+8, 2017-11-25 08:17 , Processed in 0.134266 second(s), 14 queries , Memcache On.

    苏公网安备 32059002001056号

    Powered by Discuz!

    回顶部