OPENCV例子opencv-4.5.5\samples\gpu\hog.cpp的代码分析

该hog示例的主要内容为演示 HOG(Histogram of Oriented Gradient)的使用,一种基于本地像素块进行特征直方图提取的算法,将图像均匀的分成相邻的小块,然后在所有的小块内统计梯度直方图。OpenCV中,HOG被封装在了HOGDescriptor 类中。

hog.cpp示例中调用关系如图所示:

 

实例中run函数中函数调用关系如图所示:

 

实例中run函数中函数流程图如图所示:

 

实例中run函数中函数UML逻辑图如图所示:

实例run函数源代码: 

void App::run()

{

    running = true;

    cv::VideoWriter video_writer;

    Size win_stride(args.win_stride_width, args.win_stride_height);

    Size win_size(args.win_width, args.win_width * 2);

    Size block_size(args.block_width, args.block_width);

    Size block_stride(args.block_stride_width, args.block_stride_height);

    Size cell_size(args.cell_width, args.cell_width);

    cv::Ptr<cv::cuda::HOG> gpu_hog = cv::cuda::HOG::create(win_size, block_size, block_stride, cell_size, args.nbins);

    cv::HOGDescriptor cpu_hog(win_size, block_size, block_stride, cell_size, args.nbins);

    if(args.svm_load) {

        std::vector<float> svm_model;

        const std::string model_file_name = args.svm;

        FileStorage ifs(model_file_name, FileStorage::READ);

        if (ifs.isOpened()) {

            ifs["svm_detector"] >> svm_model;

        } else {

            const std::string what =

                    "could not load model for hog classifier from file: "

                    + model_file_name;

            throw std::runtime_error(what);

        }

        // check if the variables are initialized检查变量是否已初始化

        if (svm_model.empty()) {

            const std::string what =

                    "HoG classifier: svm model could not be loaded from file"

                    + model_file_name;

            throw std::runtime_error(what);

        }

        gpu_hog->setSVMDetector(svm_model);

        cpu_hog.setSVMDetector(svm_model);

    } else {

        // Create HOG descriptors and detectors here在此处创建 HOG 描述符和检测器

        Mat detector = gpu_hog->getDefaultPeopleDetector();

        gpu_hog->setSVMDetector(detector);

        cpu_hog.setSVMDetector(detector);

    }

    cout << "gpusvmDescriptorSize : " << gpu_hog->getDescriptorSize()

         << endl;

    cout << "cpusvmDescriptorSize : " << cpu_hog.getDescriptorSize()

         << endl;

    while (running)

    {

        VideoCapture vc;

        Mat frame;

        vector<String> filenames;

        unsigned int count = 1;

        if (args.src_is_video)

        {

            vc.open(args.src.c_str());

            if (!vc.isOpened())

                throw runtime_error(string("can't open video file: " + args.src));

            vc >> frame;

        }

        else if (args.src_is_folder) {

            String folder = args.src;

            cout << folder << endl;

            glob(folder, filenames);

            frame = imread(filenames[count]);   // 0 --> .gitignore

            if (!frame.data)

                cerr << "Problem loading image from folder!!!" << endl;

        }

        else if (args.src_is_camera)

        {

            vc.open(args.camera_id);

            if (!vc.isOpened())

            {

                stringstream msg;

                msg << "can't open camera: " << args.camera_id;

                throw runtime_error(msg.str());

            }

            vc >> frame;

        }

        else

        {

            frame = imread(args.src);

            if (frame.empty())

                throw runtime_error(string("can't open image file: " + args.src));

        }

        Mat img_aux, img, img_to_show;

        cuda::GpuMat gpu_img;

        // Iterate over all frames遍历所有帧

        while (running && !frame.empty())

        {

            workBegin();

            // Change format of the image更改图像格式

            if (make_gray) cvtColor(frame, img_aux, COLOR_BGR2GRAY);

            else if (use_gpu) cvtColor(frame, img_aux, COLOR_BGR2BGRA);

            else frame.copyTo(img_aux);

            // Resize image调整图像大小

            if (args.resize_src) resize(img_aux, img, Size(args.width, args.height));

            else img = img_aux;

            img_to_show = img;

            vector<Rect> found;

            // Perform HOG classification执行 HOG 分类

            hogWorkBegin();

            if (use_gpu)

            {

                gpu_img.upload(img);

                gpu_hog->setNumLevels(nlevels);

                gpu_hog->setHitThreshold(hit_threshold);

                gpu_hog->setWinStride(win_stride);

                gpu_hog->setScaleFactor(scale);

                gpu_hog->setGroupThreshold(gr_threshold);

                gpu_hog->detectMultiScale(gpu_img, found);

            }

            else

            {

                cpu_hog.nlevels = nlevels;

                cpu_hog.detectMultiScale(img, found, hit_threshold, win_stride,

                                         Size(0, 0), scale, gr_threshold);

            }

            hogWorkEnd();

            // Draw positive classified windows绘制正分类窗口

            for (size_t i = 0; i < found.size(); i++)

            {

                Rect r = found[i];

                rectangle(img_to_show, r.tl(), r.br(), Scalar(0, 255, 0), 3);

            }

            if (use_gpu)

                putText(img_to_show, "Mode: GPU", Point(5, 25), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);

            else

                putText(img_to_show, "Mode: CPU", Point(5, 25), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);

            putText(img_to_show, "FPS HOG: " + hogWorkFps(), Point(5, 65), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);

            putText(img_to_show, "FPS total: " + workFps(), Point(5, 105), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2);

            imshow("opencv_gpu_hog", img_to_show);

            if (args.src_is_video || args.src_is_camera) vc >> frame;

            if (args.src_is_folder) {

                count++;

                if (count < filenames.size()) {

                    frame = imread(filenames[count]);

                } else {

                    Mat empty;

                    frame = empty;

                }

            }

            workEnd();

            if (args.write_video)

            {

                if (!video_writer.isOpened())

                {

                    video_writer.open(args.dst_video, VideoWriter::fourcc('x','v','i','d'), args.dst_video_fps,

                                      img_to_show.size(), true);

                    if (!video_writer.isOpened())

                        throw std::runtime_error("can't create video writer");

                }

                if (make_gray) cvtColor(img_to_show, img, COLOR_GRAY2BGR);

                else cvtColor(img_to_show, img, COLOR_BGRA2BGR);

                video_writer << img;

            }

            handleKey((char)waitKey(3));

        }

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqq9668

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值