我想提取两个圆,并想知道这个圆是否同心。
我参考了一些网站和chatGPT做了一些代码,但是有限制。
我想画一个“圆”,而不是“椭圆”。
下面是图片(它是环形红色激光束)和我的算法。
import cv2
import numpy as np
# Load the Image
img = cv2.imread("covered_2.jpg", cv2.IMREAD_GRAYSCALE)
# Blur the Image
img_blur = cv2.GaussianBlur(img, (5, 5), 0)
# Image Binerize
_, img_thresh = cv2.threshold(img_blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Set the kernal size for closing
kernel = np.ones((15, 15), np.uint8)
#Closing the Image
img_close = cv2.morphologyEx(img_thresh, cv2.MORPH_CLOSE, kernel)
contours, _ = cv2.findContours(img_close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
max_contour = max(contours, key=cv2.contourArea)
# Extract the outer ellipse
ellipse = cv2.fitEllipse(max_contour)
center, axes, angle = ellipse
major_axis, minor_axis = axes
img_ellipse = np.zeros_like(img)
cv2.ellipse(img_ellipse, ellipse, 255, 2)
# Finding the end points of the major axis(?)
cos_angle = np.cos(np.deg2rad(angle))
sin_angle = np.sin(np.deg2rad(angle))
x1 = int(center[0] - 0.5 * major_axis * sin_angle)
y1 = int(center[1] + 0.5 * major_axis * cos_angle)
x2 = int(center[0] + 0.5 * major_axis * sin_angle)
y2 = int(center[1] - 0.5 * major_axis * cos_angle)
# Finding the end points of the minor axis(?)
x3 = int(center[0] - 0.5 * minor_axis * cos_angle)
y3 = int(center[1] - 0.5 * minor_axis * sin_angle)
x4 = int(center[0] + 0.5 * minor_axis * cos_angle)
y4 = int(center[1] + 0.5 * minor_axis * sin_angle)
# Draw lines on the new image
img_lines = np.zeros_like(img)
cv2.line(img_lines, (x1, y1), (x2, y2), 255, 2)
cv2.line(img_lines, (x3, y3), (x4, y4), 255, 2)
cv2.line(img, (x1, y1), (x2, y2), 255, 2)
cv2.line(img, (x3, y3), (x4, y4), 255, 2)
cv2.ellipse(img, ellipse, 255, 2)
# Show image in the new windows
cv2.imshow('Input Image', img)
cv2.imshow('Binary Image', img_thresh)
cv2.imshow('Closed Image', img_close)
cv2.imshow('Fitted Ellipse', img_ellipse)
cv2.imshow('Extracted Lines', img_lines)
# Save the Image
cv2.imwrite('edge_detect_circle.jpg', img)
cv2.imwrite('edge_detect_circle_close.jpg', img_close)
cv2.imwrite('edge_detect_ellipse_close.jpg', img_ellipse)
cv2.imwrite('edge_detect_lines_close.jpg', img_lines)
cv2.waitKey()
cv2.destroyAllWindows()
最终的目标是补偿这个斑点图像,并绘制2个圆圈,并弄清楚它们是否同心。
原始图像是这样的:环形激光束,斑点
我试着指定一些区域并使其颜色反转以找到内部椭圆。然而,这并没有奏效。
此外,我尝试了一些霍夫循环变换,但它也没有工作。
作为最后一种方法,我使用Canny边缘检测来找出所画直线的中心,这也不起作用。
1条答案
按热度按时间l7wslrjt1#
为什么使用
fitEllipse
?如果你想要圆(不是椭圆),为什么不适合圆?
如果OpenCV不提供圆拟合(我认为是这样),请自己实现它。(“如何”将被发现时,只是谷歌。我这样做的关键字“圆拟合最小二乘”)
我用简单最小二乘法试了一下,得到了下面的拟合结果。
如你所见,结果中心位置并不完全相同。但我不能从这个结果做最终判断,因为我不知道需要多大的差异来确定这些圆不是同心圆。
这个问题被标记为[python],但我不是Python用户,所以我在C++中尝试了一下。
注意:边缘提取步骤与您的步骤不同。(我用的是最简单的方法。)因此,如果您将圆拟合到轮廓数据,结果可能会有所不同。