【发布时间】:2014-04-20 09:35:36
【问题描述】:
我正在做一个项目,我必须检查药品泡罩包装是否有丢失的药片。
我正在尝试使用 opencv 的 matchTemplate 函数。让我展示一下代码和一些结果。
int match(string filename, string templatename)
{
Mat ref = cv::imread(filename + ".jpg");
Mat tpl = cv::imread(templatename + ".jpg");
if (ref.empty() || tpl.empty())
{
cout << "Error reading file(s)!" << endl;
return -1;
}
imshow("file", ref);
imshow("template", tpl);
Mat res_32f(ref.rows - tpl.rows + 1, ref.cols - tpl.cols + 1, CV_32FC1);
matchTemplate(ref, tpl, res_32f, CV_TM_CCOEFF_NORMED);
Mat res;
res_32f.convertTo(res, CV_8U, 255.0);
imshow("result", res);
int size = ((tpl.cols + tpl.rows) / 4) * 2 + 1; //force size to be odd
adaptiveThreshold(res, res, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, size, -128);
imshow("result_thresh", res);
while (true)
{
double minval, maxval, threshold = 0.8;
Point minloc, maxloc;
minMaxLoc(res, &minval, &maxval, &minloc, &maxloc);
if (maxval >= threshold)
{
rectangle(ref, maxloc, Point(maxloc.x + tpl.cols, maxloc.y + tpl.rows), CV_RGB(0,255,0), 2);
floodFill(res, maxloc, 0); //mark drawn blob
}
else
break;
}
imshow("final", ref);
waitKey(0);
return 0;
}
这里有一些图片。
优质泡罩包装的“样品”图片:
从“示例”图像中裁剪的模板:
带有“样本”图像的结果:
检测到此包装中缺少的平板电脑:
但这里有问题:
我目前不知道为什么会发生这种情况。任何建议和/或帮助表示赞赏。
我遵循和修改的原始代码在这里:http://opencv-code.com/quick-tips/how-to-handle-template-matching-with-multiple-occurences/
【问题讨论】:
-
我已经为你编辑了图片。 +1 提出一个很好的问题
-
死你试试不同的阈值?你能达到的最高值是0.8吗?另外,您是否尝试使用其他互相关方法,例如 SQDIFF_NORMED 而不是 CCOEFF_NORMED?
-
更仔细地查看代码,将相关结果转换为 8 位,然后对其运行自适应阈值,因此您传递给 MinMaxLoc 的图像已经二值化,因此更改 0.8 阈值将没有效果。我不确定您从中获得了什么,在原始 res_32f 中搜索最大值不会得到更好的结果吗?
-
@HugoRune:原始代码在 CV_32FC1 结果图像上运行 minMaxLoc。但是由于我正在尝试进行近似匹配,因此首先在没有 AdaptiveThreshold 的情况下运行 minMaxLoc 会返回太多的失火。
标签: opencv inspection matchtemplate