Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python在有限大小的图像中查找未填充圆_Python_Opencv - Fatal编程技术网

使用Python在有限大小的图像中查找未填充圆

使用Python在有限大小的图像中查找未填充圆,python,opencv,Python,Opencv,试图在一个有有限半径的圆中找到一个圆。开始使用OpenCV中的“HoughCircles”方法作为参数,它似乎与我的情况非常相关。但它没有找到它。看起来图像可能需要更多的预处理才能可靠地找到。因此,开始在opencv中使用不同的阈值,但没有成功。是图像的一个示例(请注意,图像的整体强度会有所不同,但圆的半径始终保持不变~45像素) 这是我到目前为止所做的尝试 image = cv2.imread('image1.bmp', 0) img_in = 255-image mean_val = int

试图在一个有有限半径的圆中找到一个圆。开始使用OpenCV中的“HoughCircles”方法作为参数,它似乎与我的情况非常相关。但它没有找到它。看起来图像可能需要更多的预处理才能可靠地找到。因此,开始在opencv中使用不同的阈值,但没有成功。是图像的一个示例(请注意,图像的整体强度会有所不同,但圆的半径始终保持不变~45像素)

这是我到目前为止所做的尝试

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()