• Linux环境下Arm端源码编译OpenCV+ncnn目标检测模型实例运行调试完整实践记录


    今天需要在嵌入式设备端运行C的程序,里面有依赖OpenCV的部分,这就需要编译安装好OpenCV才行,这个对于我来说还是比较陌生的,我很少用C,所以这里面也没少折腾,一路上遇上了很多的报错,这里我将完整的安装实践记录下来备忘,也希望帮到有需要的人。

    首先是下载所需要的源码数据:

    OpenCV项目仓库在这里,首页截图如下所示:

     很火的项目了。

     网速比较好的话可以使用下面的命令:

    git clone https://github.com/opencv/opencv.git

    我是使用git下载老是提示下载失败,所以我是直接在页面端下载项目,之后上传的。

     下载完成如下:

     接下来下载另一个项目opencv_contrib,地址在这里,首页截图如下所示:

     网络好的话可以使用如下命令:

    git clone https://github.com/opencv/opencv_contrib.git

    同样我还是直接选择了页面端下载项目,如下:

     下载完成如下:

     之后上传到Linux环境下,选择自己想要安装的路径,进入该路径,执行:

    mkdir opencv_build && cd opencv_build

    这里创建opencv_build目录用于存放OpenCV相关的项目。

    首先安装一下所需要的基础环境:

    1. sudo apt-get install build-essential
    2. sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
    3. sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
    4. sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev liblapacke-dev
    5. sudo apt-get install libxvidcore-dev libx264-dev
    6. sudo apt-get install libatlas-base-dev gfortran
    7. sudo apt-get install ffmpeg

    在查资料的过程中了解到其实OpenCV编译基本都会报错的,最先的报错就是缺少各种各样的文件,所以这里我选择将一些常见报错所需要的文件提前下载下来传到对应目录下,文件在这里

     接下来解压缩:

    1. #解压缩
    2. unzip opencv-4.x.zip
    3. unzip opencv_contrib-4.x.zip
    4. #重命名
    5. mv opencv-4.x opencv
    6. mv opencv_contrib-4.x opencv_contrib
    7. #复制移动
    8. cp -r opencv_contrib opencv

    之后进入OpenCV目录,执行:

    mkdir build & cd build

    接下来基于cmake命令来生成makefile文件,我这里直接给出来最终成功好用的命令,避免重走弯路:

    1. cmake -D ENABLE_PRECOMPILED_HEADERS=OFF -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D OPENCV_EXTRA_MODULES_PATH=/root/opencv_build/opencv/opencv_contrib/modules/ ..

    这里面的OPENCV_EXTRA_MODULES_PATH是需要自己根据自己的安装路径进行调整的,比如我这里的安装路径是:/root/opencv_build/,仿照着替换自己的即可。

    这个过程需要的时间比较久,根据自己的硬件条件大家所需要的时间也是不一样的,静静等待即可,执行完成后执行如下命令启动编译:

    make -j8

    这里我就遇上了一个报错如下:

    c++: internal compiler error: Killed (program cc1plus) Please submit a full bug report, with preproc

    查资料发现:这是因为编译安装时所需要的内存不够了,解决这个问题最简单直接有效的办法就是不载指定多核编译,直接make即可,这样的缺点就是速度比较慢,不过只要不报错就行了,等待编译完成之后即可安装了。

    make install

    输出如下:

     这里我其实也遇到了一个报错:

    1. CMake Error at lib/cmake_install.cmake:48 (file):
    2. file INSTALL cannot copy file
    3. "/cmake/t3/build/lib/libhello.so.1.2" to
    4. "/usr/lib/libhello.so.1.2".

    查询网上给的解决方案说的是权限不足,但是我本身就是root权限执行操作的,不可能是权限不足的问题,这个问题网上清一色的答案全部都是说权限不足,搞得我很苦恼,实在找不到解决办法的时候我突然想到是否可以手动复制一下这个文件到指定的目录里面去呢?

    结果我手动执行cp命令之后就发现真正的问题所在了,原来是我的磁盘满了,导致没有多余的空间可以复制文件了!多么白痴的原因啊,我赶紧删除了压缩包和一些其他的文件数据腾出来了一定的磁盘空间,重新执行make install这次终于成功安装完成了。

    最后我查看版本信息:

    pkg-config --modversion opencv4

    结果又报错了:

     详情如下:

    1. Package opencv4 was not found in the pkg-config search path.
    2. Perhaps you should add the directory containing `opencv4.pc'
    3. to the PKG_CONFIG_PATH environment variable

    关于这个报错,网上的资料也挺多,但是很多讲的很杂乱,不利于新手学习解决,这里我找到了一个比较好的文章,就是按照这个步骤直接解决了,文章在这里

     这里是解决方案:

     核心思想就是要自己在这个pkgconfig目录下创建opencv.pc文件,并将相应的信息写入opencv.pc中,报错pkgconfig可以读取到,我发现本地连pkgconfig这个目录都没有,就直接手动创建了这个目录:

    1. mkdir pkgconfig
    2. cd pkgconfig
    3. vim opencv.pc

    然后将下面的信息写入:

    1. prefix=/usr/local
    2. exec_prefix=${prefix}
    3. includedir=${prefix}/include
    4. libdir=${exec_prefix}/lib
    5. Name: opencv
    6. Description: The opencv library
    7. Version:4.x
    8. Cflags: -I${includedir}/opencv4
    9. Libs: -L${libdir} -lopencv_stitching -lopencv_objdetect -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_ml -lopencv_imgproc -lopencv_flann -lopencv_core

    最后一步就是修改环境变量:

    export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

     到这里OpenCV的编译安装就结束了。

    我这里安装OpenCV是做目标检测使用的,所以这里简单拿一个样例跑一下看看:

    1. #include "yolo-fastestv2.h"
    2. int main()
    3. {
    4. static const char* class_names[] = {
    5. "person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck", "boat", "traffic light",
    6. "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat", "dog", "horse", "sheep", "cow",
    7. "elephant", "bear", "zebra", "giraffe", "backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee",
    8. "skis", "snowboard", "sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard",
    9. "tennis racket", "bottle", "wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
    10. "sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake", "chair", "couch",
    11. "potted plant", "bed", "dining table", "toilet", "tv", "laptop", "mouse", "remote", "keyboard", "cell phone",
    12. "microwave", "oven", "toaster", "sink", "refrigerator", "book", "clock", "vase", "scissors", "teddy bear",
    13. "hair drier", "toothbrush"
    14. };
    15. yoloFastestv2 api;
    16. api.loadModel("./model/yolo-fastestv2-opt.param",
    17. "./model/yolo-fastestv2-opt.bin");
    18. cv::Mat cvImg = cv::imread("test.jpg");
    19. std::vector boxes;
    20. api.detection(cvImg, boxes);
    21. for (int i = 0; i < boxes.size(); i++) {
    22. std::cout<" "<" "<" "<
    23. <<" "<" "<
    24. char text[256];
    25. sprintf(text, "%s %.1f%%", class_names[boxes[i].cate], boxes[i].score * 100);
    26. int baseLine = 0;
    27. cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
    28. int x = boxes[i].x1;
    29. int y = boxes[i].y1 - label_size.height - baseLine;
    30. if (y < 0)
    31. y = 0;
    32. if (x + label_size.width > cvImg.cols)
    33. x = cvImg.cols - label_size.width;
    34. cv::rectangle(cvImg, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),
    35. cv::Scalar(255, 255, 255), -1);
    36. cv::putText(cvImg, text, cv::Point(x, y + label_size.height),
    37. cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));
    38. cv::rectangle (cvImg, cv::Point(boxes[i].x1, boxes[i].y1),
    39. cv::Point(boxes[i].x2, boxes[i].y2), cv::Scalar(255, 255, 0), 2, 2, 0);
    40. }
    41. cv::imwrite("output.png", cvImg);
    42. return 0;
    43. }

    编译命令如下:

    g++ -g -o demo demo.cpp src/yolo-fastestv2.cpp -I src/include -I include/ncnn lib/libncnn.a `pkg-config --libs --cflags opencv` -fopenmp
    

    执行完成后生成可执行文件:

     执行报错:

     详情如下:

    error while loading shared libraries: libopencv_imgcodecs.so.406: cannot ope

    报错本质不难理解就是文件找不到了,这里实在是不想折腾配置了就采用一个简单的办法来解决,不是找不到吗?你找不到我就把这个文件所在目录加到路径路面去让你能找到不就行了,执行:

    export LD_LIBRARY_PATH=/root/opencv_build/opencv/build/lib/:$LD_LIBRARY_PATH
    

     重新执行demo,结果如下:

     可以看到:已经能够正常计算输出了,我们看下原始数据和结果数据。

    test.jpg

     output.png

     到这里OpenCV源码编译安装、深度学习检测项目实例运行就已经全部结束了,记录一下。

  • 相关阅读:
    01 背包
    轨迹预测相关论文--持续更新
    MITSUBISHI A1SJ51T64电源单元
    React(1)-jsx语法(element,vDOM)
    手把手创建属于自己的ASP.NET Croe Web API项目
    【数组】通过翻转子数组使两个数组相等
    【论文笔记】—曝光不足图像增强—Supervised—DeepUPE—2019-CVPR
    MySQL8.0.26—Linux版安装详细教程
    iNFTnews | 周杰伦18年前未发布的作品Demo,藏在了区块链技术里
    wordpress后台不能登录(多次重定向),前台样式里面https加载不上该怎么办呢?
  • 原文地址:https://blog.csdn.net/Together_CZ/article/details/126588000