gpt4 book ai didi

python - 如果使用OpenCV的HoughCircles,是否有推荐的方法来确定minRadius以便在图像中找到1个圆?

转载 作者:行者123 更新时间:2023-12-02 17:20:58 27 4
gpt4 key购买 nike

我需要找出选择OpenCV cv2.HoughCircles function中使用的minRadius值的最佳方法。

我正在努力提高可进行美国稀有硬币分类的Tensorflow CNN的准确性。目前,美国有线电视新闻网(CNN)正在审查的> 10k张图像,所有尺寸从300x300到1024x1024

为了提高模型的准确性,我尝试在训练之前将硬币从图像中拉出,并且仅在硬币上而不是在其周围训练模型。

下面的代码在将硬币检测为圆形时可以正常工作,但是我必须尝试几个minRadius值才能使HoughCircles函数正常工作。

在某些情况下,minRadius = 270在600x600和785x1024上有效,而在其他情况下,只有r = 200在600x600和785x1024上有效,但在785x1024上无效。在其他情况下,只有r = 318有效,而没有317或319有效。我没有找到一致的方法。

问题:是否存在建议的方法来确定minRadius以在图像中找到1个圆?假设图像大小不同且硬币占图像的50%至90%

这是典型图像的示例:https://i.ebayimg.com/images/g/r5oAAOSwH8VeHNBf/s-l1600.jpg
https://i.ebayimg.com/images/g/~JsAAOSwGtdeyFfU/s-l1600.jpg

image = cv2.imread(r"C:\testimages\70a.jpg")
output = image.copy()
height, width = image.shape[:2]

minRadius = 200
maxRadius =0

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
circles = cv2.HoughCircles(image=gray,
method=cv2.HOUGH_GRADIENT,
dp=1.2,
minDist=200*minRadius, #something large since we are looking for 1
param1=200,
param2=100,
minRadius=minRadius,
maxRadius=maxRadius
)

#Draw the circles detected
if circles is not None:
# convert the (x, y) coordinates and radius of the circles to integers
circlesRound = np.round(circles[0, :]).astype("int")
# loop over the (x, y) coordinates and radius of the circles
for (x, y, r) in circlesRound:
cv2.circle(output, (x, y), r, (0, 255, 0), 4)

plt.imshow(output)
else:
print ('No circles found')

最佳答案

这是通过将椭圆拟合到从阈值图像中提取的最大轮廓来实现的。如果需要,可以使用椭圆的主要半径和次要半径作为霍夫圆的近似值。

输入:

enter image description here

import cv2
import numpy as np

# read input
img = cv2.imread('s-l1600.jpg')

# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# threshold
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# apply morphology open and close
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (21,21))
morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel)

# find largest contour
contours = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)

# fit ellipse to contour and get ellipse center, minor and major diameters and angle in degree
ellipse = cv2.fitEllipse(big_contour)
(xc,yc),(d1,d2),angle = ellipse
print('center: ',xc,',',yc)
print('diameters: ',d1,',',d2)

# draw ellipse
result = img.copy()
cv2.ellipse(result, ellipse, (0, 0, 255), 2)

# draw circle at center
xc, yc = ellipse[0]
cv2.circle(result, (int(xc),int(yc)), 5, (0, 255, 0), -1)

cv2.imwrite("s-l1600_thresh.jpg", thresh)
cv2.imwrite("s-l1600_morph.jpg", morph)
cv2.imwrite("s-l1600_ellipse.jpg", result)

cv2.imshow("s-l1600_thresh", thresh)
cv2.imshow("s-l1600_morph", morph)
cv2.imshow("s-l1600_ellipse", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

大津阈值图像:

enter image description here

清除阈值图像:

enter image description here

根据输入的轮廓拟合绘制椭圆,显示椭圆的轮廓和中心:

enter image description here

椭圆参数:
center:  504.1853332519531 , 524.3350219726562
diameters: 953.078125 , 990.545654296875

这是您的其他图片。但是这里我使用了inRange()的颜色阈值。

输入:

enter image description here
import cv2
import numpy as np

# read input
img = cv2.imread('s-l1600b.jpg')

# convert to hsv
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# get color bounds of red circle
lower =(0,0,0) # lower bound for each channel
upper = (150,150,150) # upper bound for each channel

# create the mask and use it to change the colors
thresh = cv2.inRange(hsv, lower, upper)

# apply morphology open and close
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (31,31))
morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel)

# find largest contour
contours = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)

# fit ellipse to contour and get ellipse center, minor and major diameters and angle in degree
ellipse = cv2.fitEllipse(big_contour)
(xc,yc),(d1,d2),angle = ellipse
print('center: ',xc,',',yc)
print('diameters: ',d1,',',d2)

# draw ellipse
result = img.copy()
cv2.ellipse(result, ellipse, (0, 0, 255), 2)

# draw circle at center
xc, yc = ellipse[0]
cv2.circle(result, (int(xc),int(yc)), 5, (0, 255, 0), -1)

cv2.imwrite("s-l1600_thresh.jpg", thresh)
cv2.imwrite("s-l1600_morph.jpg", morph)
cv2.imwrite("s-l1600_ellipse.jpg", result)

cv2.imshow("s-l1600b_thresh", thresh)
cv2.imshow("s-l1600b_morph", morph)
cv2.imshow("s-l1600b_ellipse", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

阈值图片:

enter image description here

形态清除图像:

enter image description here

拟合椭圆并在输入上绘制的最大外部轮廓:

enter image description here

椭圆参数:
center:  497.53564453125 , 639.7144165039062
diameters: 454.8548583984375 , 458.95843505859375

关于python - 如果使用OpenCV的HoughCircles,是否有推荐的方法来确定minRadius以便在图像中找到1个圆?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62205025/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com