玩转Jetson nano系列(2):结合ncnn的实时yolov2目标检测

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/hanzy88/article/details/98474470

结合上篇玩转Jetson nano系列(1),在jetson安装好ncnn,就可以开发各种模型了。

上篇最后提到,可以通过在ncnn根目录下修改CMakefile.txt文件,去掉examples的编译注释,就可以编译出ncnn自带的模型。

一. 修改自带yolov2源码

因为自带yolov2是基于mobilenet的,而且只支持图片检测,为了让模型支持cam的实时检测,因此需要对自带的源码进行修改。

进入自带模型源码文件夹:
并备份得到新的yolov2_cam.cpp

cd ~/ncnn/examples
cp yolov2.cpp yolov2_cam.cpp

打开修改yolov2_cam.cpp

vim yolov2_cam.cpp

因为我用的是树莓派cam,设置cam参数:

这里参考自:

https://github.com/JetsonHacksNano/CSI-Camera

std::string gstreamer_pipeline (int capture_width, int capture_height, int display_width, int display_height, int framerate, int flip_method) {
    return "nvarguscamerasrc ! video/x-raw(memory:NVMM), width=(int)" + std::to_string(capture_width) + ", height=(int)" +
           std::to_string(capture_height) + ", format=(string)NV12, framerate=(fraction)" + std::to_string(framerate) +
           "/1 ! nvvidconv flip-method=" + std::to_string(flip_method) + " ! video/x-raw, width=(int)" + std::to_string(display_width) + ", height=(int)" +
           std::to_string(display_height) + ", format=(string)BGRx ! videoconvert ! video/x-raw, format=(string)BGR ! appsink";
}

通过配置gstreamer_pipeline可以修改cam的分辨率和fps

std::string pipeline = gstreamer_pipeline(capture_width,
        capture_height,
        display_width,
        display_height,
        framerate,
        flip_method);

因为这里不再需要输入图片,通过cam,所以关于图片传入的部分可以去掉,于是整个代码如下:

# 头文件加一下 #include <iostream>
int main(int argc, char** argv)
{

    int capture_width = 480 ;
    int capture_height = 360 ;
    int display_width = 480 ;
    int display_height = 360 ;
    int framerate = 30 ;
    int flip_method = 0 ;

    std::string pipeline = gstreamer_pipeline(capture_width,
        capture_height,
        display_width,
        display_height,
        framerate,
        flip_method);
    std::cout << "Using pipeline: \n\t" << pipeline << "\n";

    cv::VideoCapture cap(pipeline, cv::CAP_GSTREAMER);
    if(!cap.isOpened()) {
        std::cout<<"Failed to open camera."<<std::endl;
        return (-1);
    }

    cv::namedWindow("CSI Camera", cv::WINDOW_AUTOSIZE);
    cv::Mat img;

    std::cout << "Hit ESC to exit" << "\n" ;

    #if NCNN_VULKAN
    ncnn::create_gpu_instance();
    #endif // NCNN_VULKAN
    
    while(true)
    {
        if (!cap.read(img)) {
                std::cout<<"Capture read error"<<std::endl;
                break;
        }
        
        std::vector<Object> objects;
        detect_yolov2(img, objects);

        draw_objects(img, objects);

        int keycode = cv::waitKey(30) & 0xff ;
        if (keycode == 27) break ;
    }

    cap.release();
    cv::destroyAllWindows() ;

    #if NCNN_VULKAN
    ncnn::destroy_gpu_instance();
    #endif // NCNN_VULKAN

    return 0;
}

同时,实时显示目标检测框和label的部分也要改下,去掉下面部分:

# draw_objects() 函数内
cv::waitKey(0);

另外,我在detect_yolov2函数里改了下模型的路径,方便文件管理:

yolov2.load_param("model/mobilenet_yolo.param");
yolov2.load_model("model/mobilenet_yolo.bin");

这样,基本就改完了。

二.代码编译

在编译前,修改examples下的CMakefiles.txt,添加需要编译的yolov2_cam,如下:

add_executable(yolov2_cam yolov2_cam.cpp)
target_link_libraries(yolov2_cam ${NCNN_EXAMPLE_LINK_LIBRARIES})

同理,以后要编译自己的其他模型,在CMakefiles.txt里这样添加就行。

在玩转Jetson nano系列(1)编译完成的基础上,进入编译文件夹,如:

cd ~/ncnn/build
make -j4

就会把新改的代码编译完成。

进入生成文件夹的目录

cd examples

还记得之前改了模型的存放位置吧,把模型放在相应位置就行,如果没改就放在当前位置。

感谢下这位博主的分享,文末有模型链接:
文末有下载链接,嗯

三.测试实现

保证cam和模型都没问题的情况下,就可以执行了:

./yolov2_cam

报什么问题的话,在ncnn/examples下修改代码,然后在build下重新编译就行了。

Esc键退出

测试效果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/hanzy88/article/details/98474470
今日推荐