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 0cv::imshow(destPicFile, srcMat);cv::waitKey();
#elsecv::imwrite(destPicFile, srcMat);
#endif
}