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
}