图像识别基础之模板匹配

principle

图像匹配

本质:图像的相似度很高(矩阵的相似度很高)

code

/*
 \brief 我的图像匹配函数,获取差方和均值最小的矩阵作为结果
 \param srcPicFile:用以匹配的图像文件
 \param templatePicFile:模板图像文件
 \param destPicFile:输出的检测结果文件
*/
void MyPictureMatch(const char* srcPicFile, const char* templatePicFile, const char* destPicFile)
{
    if ((!srcPicFile) || (!templatePicFile) || (!destPicFile))
    {
        return;
    }

    cv::Mat srcMat;
    cv::Mat templateMat;
    cv::Mat srcGrayMat;
    cv::Mat templateGrayMat;
    uint32_t templateMatSize = 0;
    cv::Rect mask;
    cv::Mat subSrcGrayMat;
    cv::Mat caculationMat;
    struct recorde {
        int x;
        int y;
        double caculation;
    };
    recorde recorder;
    std::vector<recorde> recordes;

    srcMat = cv::imread(srcPicFile);
    templateMat = cv::imread(templatePicFile);

    if (srcMat.size < templateMat.size) {
        fprintf(stdout, "srcMat.size < templateMat.size\n");
        return;
    }

    templateMatSize = templateMat.cols * templateMat.rows;

    cv::cvtColor(srcMat, srcGrayMat, 
                cv::ColorConversionCodes::COLOR_RGB2GRAY);

    cv::cvtColor(templateMat, templateGrayMat, 
                cv::ColorConversionCodes::COLOR_RGB2GRAY);

    mask.width = templateGrayMat.cols;
    mask.height = templateGrayMat.rows;

    caculationMat.create(cv::Size(templateGrayMat.cols, templateGrayMat.rows), templateGrayMat.type());

    for (int i = 0; (i + mask.height) < srcGrayMat.rows; ++i)
    {
        for (int j = 0; (j + mask.width) < srcGrayMat.cols; ++j)
        {
            mask.x = j;
            mask.y = i;
            recorder.x = mask.x;
            recorder.y = mask.y;
            srcGrayMat(mask).copyTo(subSrcGrayMat);
            cv::subtract(subSrcGrayMat, templateGrayMat, caculationMat);
            cv::multiply(caculationMat, caculationMat, caculationMat);
            cv::Scalar sum = cv::sum(caculationMat);
            recorder.caculation = sum(0);
            recorder.caculation = recorder.caculation / templateMatSize;
            recordes.push_back(recorder);
            // fprintf(stderr, "recorder.caculation:%lf\n", recorder.caculation);
        }
    }

    auto cmp = [](const recorde& p1, const recorde& p2)->bool {
        if (p1.caculation < p2.caculation)
        {
            return true;
        }
        return false;
    };

    std::sort(recordes.begin(), recordes.end(), cmp);

    fprintf(stdout, "recordes[0]:%d,%d,%lf\n", recordes[0].x, recordes[0].y, recordes[0].caculation);

    mask.x = recordes[0].x;
    mask.y = recordes[0].y;

    cv::rectangle(srcMat, mask, cv::Scalar(0, 255, 0));
    
    // imshow需要显示驱动
#if 0
    cv::imshow(destPicFile, srcMat);
    cv::waitKey();
#else
    cv::imwrite(destPicFile, srcMat);
#endif
}

performance

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值