图像识别基础之模板匹配

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 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

图像识别基础之模板匹配_第1张图片

你可能感兴趣的:(图像处理,opencv,计算机视觉,c++)