Ein möglicher Ansatz ist es, zunächst threshold
das Bild von einigen der Lärm um den Kreis zu befreien. Dann können Sie den Rand des Kreises mit der Kantenerkennung Canny
extrahieren. Schließlich, findNonZero
, um eine Liste der Pixel-Koordinaten zu erhalten.
Ich habe zuerst einen schnellen Prototyp mit 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)])
Und portiert es dann auf C++, einige zusätzliche Code hinzufügen alle Zwischenbilder zu speichern und die gefundenen Pixel zu zeichnen.
#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);
}
Ausgabe von threshold
:
Ausgabe von Canny
:
Re-geplotteten Punkte:
012.351.
Wenn Sie die Kreisparameter benötigen, können Sie 'minEnclosingCircle' verwenden – Miki
Vielen Dank :) –