OpenCV:多线程加速的多尺度模板匹配

OpenCV中的模板匹配 matchTemplate 一直被诟病,原因是不能多尺度识别且不能旋转识别,后者比较复杂,这里只讨论前者。网上多数示例都是从一张图上截取一个目标,然后进行匹配识别,效果很好但明显没有实用性。其实通过设置“尺度池” Scaling Pool可以很好的解决这个问题,用尺度不一的模板进行匹配不就可以了吗?再以多线程加速,各尺度独立匹配,最后取最佳结果,这就是多尺度的思路。
在这里插入图片描述
另外,基于特征(SIFT/SURF等)的目标匹配则不需要考虑尺度和角度问题,本文参考 holybin大神的博客 进行了代码移植,识别结果在后面一并展示。


本文环境:Win10 + OpenCV4.1 + Contrib4.1 + VS2019


直接上代码:(匹配的结果评价指标有很多,这里选的是TM_CCOEFF_NORMED

void TemplateMatching(cv::Mat& src, cv::Mat& tmpl) {
    vector<double> scales = { 0.5, 0.75, 1.25, 1.5 };
    vector<std::future<Result>> results(scales.size());
    for (int i = 0; i < scales.size(); ++i) {
        results[i] = std::async(launch::async, [this, &src, &tmpl, scales, i]() -> Result
            {
                Mat t;   
                Size2d size(tmpl.cols * scales[i], tmpl.rows * scales[i]);
                resize(tmpl, t, size);
                Mat dst(src.size(), src.type());
                matchTemplate(src, t, dst, TM_CCOEFF_NORMED);
                cv::Point minPoint, maxPoint, matchLoc;
                double minVal(-1), maxVal(-1), score(-1);
                cv::minMaxLoc(dst, &minVal, &maxVal, &minPoint, &maxPoint);
                double weight = scales[i] < 1. ? scales[i] : 1. / scales[i];
                score = maxVal * weight;
                matchLoc = maxPoint;
                return Result{ score , Rect(matchLoc.x, matchLoc.y,t.cols,t.rows) };
            });
    }

    Mat processImg = src.clone();
    Result maxRes;
    cv::RNG rng(time(0));
    for (int i = 0; i < scales.size(); ++i) {
        results[i].wait();
        Result res = results[i].get();
        Scalar color(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        cv::putText(processImg, to_string(res.score), Point(res.bbox.x, res.bbox.y), 0, 1, color, 2);
        cv::rectangle(processImg, res.bbox, color, 2, 8);
        if (res.score > maxRes.score) {
            maxRes = res;
        }
    }
    cv::imshow("Template Matching Process", processImg);

    Mat img = src.clone();
    cv::putText(img, to_string(maxRes.score), Point(maxRes.bbox.x, maxRes.bbox.y), 0, 1, 255, 2);
    cv::rectangle(img, maxRes.bbox, Scalar(0, 255, 0), 2, 8);
    cv::imshow("Template Matching", img);
    cv::waitKey(1);
}

识别结果:
在这里插入图片描述

整个工程代码已经上传,包括两种识别方法:多线程加速的多尺度模板匹配SURF特征匹配

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多尺度模板匹配是一种在图像中寻找多个尺度下的目标的方法。在OpenCV中,可以使用cv2.matchTemplate()函数结合不同尺度的模板图像来实现多尺度模板匹配。具体步骤如下: 1. 定义一个尺度列表,包含不同尺度的模板图像。 2. 遍历尺度列表,对每个尺度的模板图像进行模板匹配。 3. 使用cv2.resize()函数将原始图像和当前尺度的模板图像调整为相同大小。 4. 使用cv2.matchTemplate()函数对调整后的图像进行模板匹配,得到匹配结果。 5. 根据匹配结果,可以使用cv2.minMaxLoc()函数找到最佳匹配位置,并绘制矩形框标记目标位置。 需要注意的是,不同的匹配方法可以通过设置cv2.matchTemplate()函数的第三个参数来选择,例如cv2.TM_CCOEFF、cv2.TM_CCOEFF_NORMED、cv2.TM_CCORR、cv2.TM_CCORR_NORMED、cv2.TM_SQDIFF、cv2.TM_SQDIFF_NORMED。这些方法在匹配过程中会计算匹配度的不同指标,可以根据具体需求选择适合的方法。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [使用Python,OpenCV进行模板匹配单对象、多对象及多尺度模板匹配](https://blog.csdn.net/qq_40985985/article/details/119043651)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [[opencv-python] cv2.matchtemplate(...)模板匹配-多尺度模板匹配算法](https://blog.csdn.net/weixin_43151193/article/details/125094516)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值