使用OpenCV MatchTemplate进行泡罩包装检查 [英] Using opencv matchtemplate for blister pack inspection

查看:120
本文介绍了使用OpenCV MatchTemplate进行泡罩包装检查的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个项目,其中我必须检查药品泡罩包装中的药片是否丢失.

I am doing a project in which I have to inspect pharmaceutical blister pack for missing tablets.

我正在尝试使用opencv的matchTemplate函数.让我显示代码,然后显示一些结果.

I am trying to use opencv's matchTemplate function. Let me show the code and then some results.

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

这是一些图片.

优质泡罩包装的样本"图像:

The "sample" image of a good blister pack:

从样本"图像裁剪的模板:

The template cropped from "sample" image:

带有样本"图像的结果:

Result with "sample" image:

检测到此包中缺少平板电脑:

Missing tablet from this pack is detected:

但是这里有问题:

我目前不知道为什么会这样.任何建议和/或帮助都将受到赞赏.

I currently don't have any idea why this happens. Any suggestion and/or help is appreciated.

我遵循和修改的原始代码在这里: http://opencv-code.com/quick-tips/how-to-handle-template-matching-with-multiple-occurences/

The original code that I followed and modified is here: http://opencv-code.com/quick-tips/how-to-handle-template-matching-with-multiple-occurences/

推荐答案

我为自己的问题找到了解决方案.我只需要在图像和模板上都应用Canny边缘检测器,然后再将它们扔到matchTemplate函数即可.完整的工作代码:

I found a solution for my own question. I just need to apply Canny edge detector on both image and template before throwing them to matchTemplate function. The full working code:

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

    Mat gref, gtpl;
    cvtColor(ref, gref, CV_BGR2GRAY);
    cvtColor(tpl, gtpl, CV_BGR2GRAY);

    const int low_canny = 110;
    Canny(gref, gref, low_canny, low_canny*3);
    Canny(gtpl, gtpl, low_canny, low_canny*3);

    imshow("file", gref);
    imshow("template", gtpl);

    Mat res_32f(ref.rows - tpl.rows + 1, ref.cols - tpl.cols + 1, CV_32FC1);
    matchTemplate(gref, gtpl, 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, -64);
    imshow("result_thresh", res);

    while(1) 
    {
        double minval, maxval;
        Point minloc, maxloc;
        minMaxLoc(res, &minval, &maxval, &minloc, &maxloc);

        if(maxval > 0)
        {
            rectangle(ref, maxloc, Point(maxloc.x + tpl.cols, maxloc.y + tpl.rows), Scalar(0,255,0), 2);
            floodFill(res, maxloc, 0); //mark drawn blob
        }
        else
            break;
    }

    imshow("final", ref);
    waitKey(0);

    return 0;
}

任何改进的建议均受到赞赏.我非常担心代码的性能和健壮性,因此我正在寻找所有想法.

Any suggestion for improvement is appreciated. I am strongly concerned about performance and robustness of my code, so I am looking for all ideas.

现在有两件事让我感到不安:较低的Canny阈值和adaptiveThreshold函数的负常数.

There are 2 things that got my nerves now: the lower Canny threshold and the negative constant on adaptiveThreshold function.

这是您要求的结果:)

模板:

测试图片,缺少2片:

模板和测试图像的Canny结果:

Canny results of template and test image:

matchTemplate结果(转换为CV_8U):

matchTemplate result (converted to CV_8U):

adaptiveThreshold之后:

After adaptiveThreshold:

最终结果:

这篇关于使用OpenCV MatchTemplate进行泡罩包装检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆