c++ - 如何通过opencv计算图像中两个圆的距离

标签 c++ opencv image-processing hough-transform

带有两个圆圈的图片

enter image description here

我有一个包含两条纤维的图像(在图像中显示为两个圆圈)。如何计算两根光纤的距离?

我发现很难检测到光纤的位置。我试过使用HoughCircles函数,但是参数很难优化,而且很多时候不能精确定位圆。我应该先减去背景还是有其他方法?非常感谢!

最佳答案

很遗憾,您没有显示预处理步骤。在我的方法中,我将执行以下操作:

  1. 将输入图像转换为灰度(参见 cvtColor)。
  2. 中值模糊,保持“边缘”(参见 medianBlur)。
  3. 自适应阈值(参见 adaptiveTreshold)。
  4. 去除小噪声的形态学开放(参见 morphologyEx)。
  5. 通过 HoughCircles 查找圈子。
  6. 此处未完成:可能对找到的圈子进行改进。排除太小或太大的圆圈。使用您拥有的所有先前信息!例如,圆圈到底可以有多大?

这是我的全部代码:

// Read image.
cv::Mat img = cv::imread("images/i7aJJ.jpg", cv::IMREAD_COLOR);

// Convert to grayscale for processing.
cv::Mat blk;
cv::cvtColor(img, blk, cv::COLOR_BGR2GRAY);

// Median blurring to improve following thresholding.
cv::medianBlur(blk, blk, 11);

// Adaptive thresholding.
cv::adaptiveThreshold(blk, blk, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 51, -2);

// Morphological opening to get rid of small noise.
cv::morphologyEx(blk, blk, cv::MORPH_OPEN, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3)));

// Find circles using Hough transform.
std::vector<cv::Vec4f> circles;
cv::HoughCircles(blk, circles, cv::HOUGH_GRADIENT, 1.0, 300, 50, 25, 100);

// TODO: Refinement of found circles, if there are more than two.
// For example, calculate areas: Neglect too small or too large areas.
// Compare all areas, and keep the two with nearly matching areas and
// suitable areas.

// Draw circles in input image.
for (Vec4f& circle : circles) {
    cv::circle(img, cv::Point(circle[0], circle[1]), circle[2], cv::Scalar(0, 0, 255), 4);
    cv::circle(img, cv::Point(circle[0], circle[1]), 5, cv::Scalar(0, 255, 0), cv::FILLED);
}

// --- Assuming there are only the two right circles left from here. --- //

// Draw some debug output in input image.
const cv::Point c1 = cv::Point(circles[0][0], circles[0][1]);
const cv::Point c2 = cv::Point(circles[1][0], circles[1][1]);
cv::line(img, c1, c2, cv::Scalar(255, 0, 0), 2);

// Calculate distance, and put in input image.
double dist = cv::norm(c1 - c2);
cv::putText(img, std::to_string(dist), cv::Point((c1.x + c2.x) / 2 + 20, (c1.y + c2.y) / 2 + 20), cv::FONT_HERSHEY_COMPLEX, 1.0, cv::Scalar(255, 0, 0));

最终输出如下所示:

Final output

HoughCircles 操作之前的中间图像如下所示:

Intermediate image

总的来说,我对 HoughCircles 并没有那么怀疑。您“只需”注意您的预处理。

希望对您有所帮助!

关于c++ - 如何通过opencv计算图像中两个圆的距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56748740/

相关文章:

c++ - 将 OGRE::Image 转换为 cv::Mat

java - 将 OpenCV 转换为 JavaCV - 在函数 cvHoughLines2() 中需要帮助

opencv - 如何为 OpenCV 中的 InRange 阈值选择最佳 HSV 值

image-processing - OpenCV (Emgu.CV) -- 使用 alpha 合成图像

c++ - 将通用模板类作为仿函数参数传递

c++ - 如何终止DLL中的log4cplus?

c++ - OpenCV 3.0 videoio 错误

android - 如何使用android-openCV在android中流式传输多个CameraBridgeViewBase?

c++/qt - 没有这样的插槽 - 继承

c++ - 与参数包声明混淆,C++