二进制图像中磁盘的半径

Yve*_*ust 4 opencv image-processing

我有像这样的二值化图像:

在此输入图像描述

我需要确定内部实心磁盘的中心和半径.正如您所看到的,它被一个接触它的纹理区域所包围,因此简单的连接组件检测不起作用.无论如何,周边的很大一部分都有一个空隙.

可能的治愈方法可能是通过侵蚀直到所有纹理消失或从磁盘断开,但这可能是耗时的并且迭代次数不确定.(此外,在一些不幸的情况下,磁盘上有小孔,随着侵蚀而增长.)

有没有更好的建议以强大而快速的方式解决这个问题?(我标记了OpenCV,但这不是强制性的,重要的是方法.)

Mik*_*iki 6

您可以:

  1. 反转图像
  2. 找到仅包含零最大轴对齐矩形(我使用了我的答案中的 C++代码).算法非常快.
  3. 从矩形中获取圆的中心和半径

在此输入图像描述

码:

#include <opencv2\opencv.hpp>

using namespace std;
using namespace cv;

// https://stackoverflow.com/a/30418912/5008845
cv::Rect findMaxRect(const cv::Mat1b& src)
{
    cv::Mat1f W(src.rows, src.cols, float(0));
    cv::Mat1f H(src.rows, src.cols, float(0));

    cv::Rect maxRect(0,0,0,0);
    float maxArea = 0.f;

    for (int r = 0; r < src.rows; ++r)
    {
        for (int c = 0; c < src.cols; ++c)
        {
            if (src(r, c) == 0)
            {
                H(r, c) = 1.f + ((r>0) ? H(r-1, c) : 0);
                W(r, c) = 1.f + ((c>0) ? W(r, c-1) : 0);
            }

            float minw = W(r,c);
            for (int h = 0; h < H(r, c); ++h)
            {
                minw = std::min(minw, W(r-h, c));
                float area = (h+1) * minw;
                if (area > maxArea)
                {
                    maxArea = area;
                    maxRect = cv::Rect(cv::Point(c - minw + 1, r - h), cv::Point(c+1, r+1));
                }
            }
        }
    }

    return maxRect;
}


int main()
{
    cv::Mat1b img = cv::imread("path/to/img", cv::IMREAD_GRAYSCALE);

    // Correct image
    img = img > 127;

    cv::Rect r = findMaxRect(~img);

    cv::Point center ( std::round(r.x + r.width / 2.f), std::round(r.y + r.height / 2.f));
    int radius = std::sqrt(r.width*r.width + r.height*r.height) / 2;

    cv::Mat3b out;
    cv::cvtColor(img, out, cv::COLOR_GRAY2BGR);
    cv::rectangle(out, r, cv::Scalar(0, 255, 0));
    cv::circle(out, center, radius, cv::Scalar(0, 0, 255));

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 这很酷!我会尝试以某种方式找到圆圈的内部,然后向外拍摄光线,直到黑色像素被击中,然后使用RANSAC来适应圆圈.但是你的方法非常简单,看起来非常强大. (2认同)