使用Python在有限大小的图像中查找未填充圆
试图在一个有有限半径的圆中找到一个圆。开始使用OpenCV中的“HoughCircles”方法作为参数,它似乎与我的情况非常相关。但它没有找到它。看起来图像可能需要更多的预处理才能可靠地找到。因此,开始在opencv中使用不同的阈值,但没有成功。是图像的一个示例(请注意,图像的整体强度会有所不同,但圆的半径始终保持不变~45像素) 这是我到目前为止所做的尝试使用Python在有限大小的图像中查找未填充圆,python,opencv,Python,Opencv,试图在一个有有限半径的圆中找到一个圆。开始使用OpenCV中的“HoughCircles”方法作为参数,它似乎与我的情况非常相关。但它没有找到它。看起来图像可能需要更多的预处理才能可靠地找到。因此,开始在opencv中使用不同的阈值,但没有成功。是图像的一个示例(请注意,图像的整体强度会有所不同,但圆的半径始终保持不变~45像素) 这是我到目前为止所做的尝试 image = cv2.imread('image1.bmp', 0) img_in = 255-image mean_val = int
image = cv2.imread('image1.bmp', 0)
img_in = 255-image
mean_val = int(np.mean(img_in))
ret, img_thresh = cv2.threshold(img_in, thresh=mean_val-30, maxval=255, type=cv2.THRESH_TOZERO)
# detect circle
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.0, 100, minRadius=40, maxRadius=50)
如果你看这张图片,圆圈很明显,它是一个薄的浅灰色圆圈,位于斑点的中心
有什么建议吗?
编辑以显示预期结果
正如您所看到的那样,预期结果应该是这样的:在原始图像上,用肉眼可以非常明显地看到圆,并且圆的半径始终相同,但不在图像上的相同位置。但是在任何给定的图像上都只有一个这样的圆
从2020年8月20日起,以下是我用来获取中心和半径的代码
from numpy import zeros as np_zeros,\
full as np_full
from cv2 import calcHist as cv2_calcHist,\
HoughCircles as cv2_HoughCircles,\
HOUGH_GRADIENT as cv2_HOUGH_GRADIENT
def getCenter(img_in, saturated, minradius, maxradius):
img_local = img_in[100:380,100:540,0]
res = np_full(3, -1)
# do some contrast enhancement
img_local = stretchHistogram(img_local, saturated)
circles = cv2_HoughCircles(img_local, cv2_HOUGH_GRADIENT, 1, 40, param1=70, param2=20,
minRadius=minradius,
maxRadius=maxradius)
if circles is not None: # found some circles
circles = sorted(circles[0], key=lambda x: x[2])
res[0] = circles[0][0]+100
res[1] = circles[0][1]+100
res[2] = circles[0][2]
return res #x,y,radii
def stretchHistogram(img_in, saturated=0.35, histMin=0.0, binSize=1.0):
img_local = img_in.copy()
img_out = img_in.copy()
min, max = getMinAndMax(img_local, saturated)
if max > min:
min = histMin+min * binSize
max = histMin+max * binSize
w, h = img_local.shape[::-1]
#create a new lut
lut = np_zeros(256)
max2 = 255
for i in range(0, 256):
if i <= min:
lut[i] = 0
elif i >= max:
lut[i] = max2
else:
lut[i] = (round)(((float)(i - min) / (max - min)) * max2)
#update image with new lut values
for i in range(0, h):
for j in range(0, w):
img_out[i, j] = lut[img_local[i, j]]
return img_out
def getMinAndMax(img_in, saturated):
img_local = img_in.copy()
hist = cv2_calcHist([img_local], [0], None, [256], [0, 256])
w, h = img_local.shape[::-1]
pixelCount = w * h
saturated = 0.5
threshold = (int)(pixelCount * saturated / 200.0)
found = False
count = 0
i = 0
while not found and i < 255:
count += hist[i]
found = count > threshold
i = i + 1
hmin = i
i = 255
count = 0
while not found and i > 0:
count += hist[i]
found = count > threshold
i = i - 1
hmax = i
return hmin, hmax
但它仍然非常不可靠。我不知道为什么很难找到一种算法,这种算法能够可靠地处理肉眼可见的事情。不知道为什么帧与帧之间的结果会有如此大的差异,即使它们之间没有变化
如有任何建议,我们将不胜感激。这里还有一些可以玩的简单,画你的圆圈:
cv2。HoughCircles
返回一个圆圈列表
注意maxRadius=100
for i in circles[0,:]:
# draw the outer circle
cv2.circle(image,(i[0],i[1]),i[2],(255,255,0),2)
# draw the center of the circle
cv2.circle(image,(i[0],i[1]),2,(255,0,255),3)
完整的工作代码(您必须更改Treshold):
导入cv2
将numpy作为np导入
image=cv2.imread('0005.bmp',0)
高度、宽度=image.shape
打印(图像.形状)
img_in=255图像
平均值=整数(np.平均值(单位:英寸))
模糊=cv2.模糊(img_in,(3,3))
ret,img_thresh=cv2.threshold(模糊,thresh=100,maxval=255,type=cv2.thresh_至零)
#检测圆
圆=cv2.霍夫圆(img_阈值,cv2.霍夫梯度,1,40,参数1=70,参数2=20,最小半径=60,最大半径=0)
打印(圆圈)
对于圆[0,:]中的i:
#检查中心是否在图片中间
如果(i[0]>width/2-30和i[0]高度/2-30和i[1]<高度/2+30):
#画外圆
cv2.圆(图像,(i[0],i[1]),i[2],(255255,0),2)
#画圆的中心
cv2.圆(图像,(i[0],i[1]),2,(255,0255),3)
cv2.imshow(“图像”,图像)
尽管如此:
键盘=cv2.等待键(2320)
如果键盘==27:
打破
cv2.destroyAllWindows()
结果:
您是否必须将此应用于其他类似的图像?试着裁剪圆周围的图像,并应用一些(也)使圆更坚固。在你的例子中,反转图像(使圆为白色),然后尝试放大或打开。然后再试一次。图像处理需要反复尝试才能看出什么是有效的。圆总是同心的吗?如果是这样的话,你可以找到它们中任何一个的中心,你已经知道半径了。谢谢Joe和Mark,他们会尝试利用你的建议(已经在做图像反转),更新原始帖子以反映预期的结果,还有更多details@Mark,对于此类型的任何给定图像,除了图像的整体强度和我试图找到的圆圈的位置不同之外,这种类型的圆圈只有一个(在原始帖子的更新附加图像中突出显示)。但是所有图像的半径都差不多Hanks Stefan,我已经有了画圆的代码(如果找到的话),只是这里没有显示代码,因为它不是实际的算法。感谢您建议使用模糊过滤器,这可能有助于使我尝试查找的圆的边缘易于使用边缘查找算法所有hough变换都不相等:您还应该尝试使用scikit image hough_circle(),因为它更适合查找那些讨厌的圆。
for i in circles[0,:]:
# draw the outer circle
cv2.circle(image,(i[0],i[1]),i[2],(255,255,0),2)
# draw the center of the circle
cv2.circle(image,(i[0],i[1]),2,(255,0,255),3)
import cv2
import numpy as np
image = cv2.imread('0005.bmp', 0)
height, width = image.shape
print(image.shape)
img_in = 255-image
mean_val = int(np.mean(img_in))
blur = cv2.blur(img_in , (3,3))
ret, img_thresh = cv2.threshold(blur, thresh=100, maxval=255, type=cv2.THRESH_TOZERO)
# detect circle
circles = cv2.HoughCircles(img_thresh, cv2.HOUGH_GRADIENT,1,40,param1=70,param2=20,minRadius=60,maxRadius=0)
print(circles)
for i in circles[0,:]:
# check if center is in middle of picture
if(i[0] > width/2-30 and i[0] < width/2+30 \
and i[1] > height/2-30 and i[1] < height/2+30 ):
# draw the outer circle
cv2.circle(image,(i[0],i[1]),i[2],(255,255,0),2)
# draw the center of the circle
cv2.circle(image,(i[0],i[1]),2,(255,0,255),3)
cv2.imshow("image", image )
while True:
keyboard = cv2.waitKey(2320)
if keyboard == 27:
break
cv2.destroyAllWindows()