首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenCV模板匹配相似对象

OpenCV模板匹配相似对象
EN

Stack Overflow用户
提问于 2016-01-09 15:12:01
回答 1查看 6.2K关注 0票数 4

我目前正在尝试使用OpenCV模板匹配功能来检测使用模板的给定图像中的所有相似对象。然而,我并不是让所有的物体(血细胞)都被检测出来,即使它们非常相似和相同。我一直在互联网上寻找解决方案,但没有得到任何解决方案。

以下是我的代码:

代码语言:javascript
复制
cv::Mat ref = cv::imread("c:\\image.jpg");
cv::Mat tpl = cv::imread("c:\\template.jpg");

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

cv::Mat res(ref.rows-tpl.rows+1, ref.cols-tpl.cols+1, CV_32FC1);
cv::matchTemplate(gref, gtpl, res, CV_TM_CCOEFF_NORMED);
cv::threshold(res, res, 0.8, 1., CV_THRESH_TOZERO);

while (true)
{
    double minval, maxval, threshold = 0.8;
    cv::Point minloc, maxloc;
    cv::minMaxLoc(res, &minval, &maxval, &minloc, &maxloc);

    if (maxval >= threshold)
    {
        cv::rectangle(
            ref,
            maxloc,
            cv::Point(maxloc.x + tpl.cols, maxloc.y + tpl.rows),
            CV_RGB(0,255,0), 2
        );
        cv::floodFill(res, maxloc, cv::Scalar(0), 0, cv::Scalar(.1), cv::Scalar(1.));
    }
    else
        break;
}

cv::imshow("reference", ref);

以下是使用的结果和图像:

给定的图像

模板

阈值设置较高时的结果(0.8/0.8)

阈值设置较低时的结果(0.6/0.3)

我对模板匹配非常陌生,有没有一种方法可以让图像中的所有对象都被检测出来?

我需要模板匹配来检测一些更复杂的图像中的细胞。

EN

回答 1

Stack Overflow用户

发布于 2016-01-12 20:18:45

在您的特定情况下,您不需要使用模板匹配。您可以仅使用红色组件来检测斑点。如果您使用OpenCV 3.0+,则可以使用cv::SimpleBlobDetector

无论如何,您可以使用cv::thresholdcv::findContours实现简单的检测器。我尝试了以下代码:

代码语言:javascript
复制
int main()
{
  const int threshVal = 30;
  const int minArea = 15 * 15;
  const int maxArea = 100 * 100;
  cv::Mat img = cv::imread("input.jpg");

  cv::Mat bgr[3];
  cv::split(img, bgr);

  cv::Mat red_img = bgr[2];
  cv::threshold(red_img, red_img, threshVal, 255, cv::THRESH_BINARY);

  vector<vector<Point>> contours;
  vector<Vec4i> hierarchy;
  cv::findContours(red_img, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

  for (int i = 0; i < contours.size(); i++)
  {
    int area = cv::contourArea(contours[i]);
    if (area < minArea || area > maxArea)
      continue;

    cv::Rect roi = cv::boundingRect(contours[i]);
    cv::rectangle(img, roi, cv::Scalar(0, 255, 0), 2);
  }

  cv::imshow("result", img);
  cv::waitKey(0);
  return 0;
}

这段代码会检测所有的血细胞:

当然,您可能需要调整三个常量(threshValminAreamaxArea)的值,以便在所有样本上获得更好的结果。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34690774

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档