在不使用霍夫圆圈的情况下检测圆圈

j.d*_*doe 5 c++ geometry opencv image-processing

我有一个圆圈的图像,我想找到圆圈但不使用霍夫圆圈.

我找到了一种方法,链接在这里.

但我找不到从白到黑的过渡坐标,因为我不知道圆圈中的x和y坐标.还有哪些其他方法,或者我如何使这种方法有效?

这是我的测试图片:

在此输入图像描述

Lam*_*ell 5

另一种方法(不仅对圆有用)是找到图像轮廓并对圆进行图像矩分析以找到它的质心:

在此处输入图片说明

在此处输入图片说明

如果您要继续进行图像处理,我建议您学习它们。它们是非常有用的方法,可以将图像转换为更有用的结构。


Dan*_*šek 4

一种可能的方法是首先对threshold图像去除圆圈周围的一些噪声。然后您可以使用边缘检测来提取圆的边缘Canny。最后,findNonZero获取像素坐标列表。


我首先用 Python 做了一个快速原型:

import cv2
import numpy as np

img = cv2.imread('circle.png', 0)
mask = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1]
edges = cv2.Canny(mask, 20, 100)
points = np.array([p[0] for p in cv2.findNonZero(edges)])
Run Code Online (Sandbox Code Playgroud)

然后将其移植到 C++,添加一些额外的代码来保存所有中间图像并绘制找到的像素。

#include <opencv2/opencv.hpp>

int main()
{
    cv::Mat img(cv::imread("circle.png", 0));

    cv::Mat mask;
    cv::threshold(img, mask, 127, 255, cv::THRESH_BINARY);

    cv::imwrite("circle_1.png", mask);

    cv::Mat edges;
    cv::Canny(mask, edges, 20, 100);

    cv::imwrite("circle_2.png", edges);

    std::vector<cv::Point2i> points;
    cv::findNonZero(edges, points);

    cv::Mat output(cv::Mat::zeros(edges.size(), CV_8UC3));
    for (auto const& p : points) {
        output.at<cv::Vec3b>(p) = cv::Vec3b(127, 255, 127);
    }
    cv::imwrite("circle_3.png", output);
}
Run Code Online (Sandbox Code Playgroud)

输出threshold

输出Canny

重新绘制像素:

  • 如果需要circle参数,可以使用`minEnendingCircle` (3认同)