【问题标题】:opencv simple blob detection, getting some undetected blobsopencv简单的blob检测,得到一些未检测到的blob
【发布时间】:2017-11-21 20:34:42
【问题描述】:

我在网上搜索了一下,并在 stackoverflow 上使用了这里的搜索,但还没有找到我在这个问题上寻找的东西。所以基本上我使用来自opencv的简单斑点检测来获取我的图像中的白色区域(这已经是二进制的)并且在非常相似的图像中我得到非常不同的结果,即检测到哪些斑点,哪些没有,在这里是定义 simpleblobdetector 时后跟参数的示例。

如您所见,有些斑点没有被检测到,这是我的检测器配置:

void blobDetect(cv::Mat img) {
    cv::SimpleBlobDetector::Params params;
    if (Daytime) {
        params.minThreshold = 23;
        params.maxThreshold = 25;
    }
    else {

        params.minThreshold = 3;
        params.maxThreshold = 5;
    }
    params.thresholdStep = 1;

    params.filterByColor = true;
    params.blobColor = 255;
    params.filterByArea = true;
    params.minArea = 300;
    params.maxArea = 400000;
    params.filterByCircularity = false;
    //params.minCircularity = "";

    params.filterByConvexity = false;
    //params.minConvexity = "";

    params.filterByInertia = false;
    //params.minInertiaRatio = "";

    cv::Ptr<cv::SimpleBlobDetector> detector = cv::SimpleBlobDetector::create(params);

    std::vector<cv::KeyPoint> keypoints;

    detector->detect(img, keypoints);

    cv::Mat im_with_keypoints;

    std::cout << keypoints.size() << std::endl;

    drawKeypoints(img, keypoints, im_with_keypoints, cv::Scalar(0, 0, 255), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

    imshow("display4", im_with_keypoints);
}

所以我问,是不是因为 blob 的形状和大小?(我怀疑这个选项,因为在某些情况下它可以找到大面积的奇怪形状)我认为简单的 blob 检测可以找到任何像素组,是它更适合圆形斑点或类似的东西?我应该考虑使用另一种算法还是构建自己的算法?或者有没有办法让我解决这个问题并提高简单斑点检测的准确性?

我知道这些问题很多,但提前感谢您提供的任何帮助!

【问题讨论】:

  • Blob 检测器是相当老的 OpenCV,为什么不查找轮廓并按区域排序?
  • 我明白你的意思,我会试试这个!我想会有更好的方法来解决这个问题,但由于我仍然缺乏经验,我无法弄清楚该走哪条路!我会发布结果 :) 谢谢!

标签: c++ opencv image-processing blob


【解决方案1】:

就像Alexander Reynolds 建议的“Blob 检测器是相当古老的 OpenCV,为什么不查找轮廓并按区域排序?”

我使用this link 作为起点。

在得到图像的轮廓后,我使用这个: "if (cv::contourArea(contours[i]) > 500)" 对小区域进行阈值处理,它工作得很好,而且比 blobdetection 工作得快得多。

再一次,Alexander,非常感谢你为我指明了正确的方向 :)

ps:按照建议,这里是完整的解决方案。

void findContours(cv::Mat img) {
    // find contours:
    std::vector<std::vector<cv::Point> > contours;
    std::vector<cv::Vec4i> hierarchy;
    findContours(img, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);

    // draw contours:
    cv::Mat imgWithContours = cv::Mat::zeros(img.rows, img.cols, CV_8UC3);
    cv::RNG rng(12345);
    for (int i = 0; i < contours.size(); i++)
    {
        if (cv::contourArea(contours[i]) > 500) {
            cv::Scalar color = cv::Scalar(rng.uniform(50, 255), rng.uniform(50, 255), rng.uniform(50, 255));
            drawContours(imgWithContours, contours, i, color, 1, 8, hierarchy, 0);
        }
    }
    imshow("display4", imgWithContours);
}

【讨论】:

  • 很高兴看到您能够按照自己的喜好进行操作!干得好,也许发布您使用的完整解决方案,以防其他人偶然发现这个问题。
猜你喜欢
  • 1970-01-01
  • 2019-11-21
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多