Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.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

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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.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
基于opencv和python的houghcirles圆检测-_Python_Opencv_Geometry_Detection - Fatal编程技术网

基于opencv和python的houghcirles圆检测-

基于opencv和python的houghcirles圆检测-,python,opencv,geometry,detection,Python,Opencv,Geometry,Detection,我正在尝试使用OpenCV的(Hough)圆检测来。。检测圆圈。我在黑色背景上创建了一个实心圆,尝试使用参数,使用模糊和所有东西,但我无法让它找到任何东西 任何想法、建议等都会很好,谢谢 我当前的代码是这样的: import cv2 import numpy as np """ params = dict(dp=1, minDist=1, circles=None, param1=300,

我正在尝试使用OpenCV的(Hough)圆检测来。。检测圆圈。我在黑色背景上创建了一个实心圆,尝试使用参数,使用模糊和所有东西,但我无法让它找到任何东西

任何想法、建议等都会很好,谢谢

我当前的代码是这样的:

import cv2
import numpy as np

"""
params = dict(dp=1,
              minDist=1,
              circles=None,
              param1=300,
              param2=290,
              minRadius=1,
              maxRadius=100)
"""

img = np.ones((200,250,3), dtype=np.uint8)
for i in range(50, 80, 1):
    for j in range(40, 70, 1):
        img[i][j]*=200

cv2.circle(img, (120,120), 20, (100,200,80), -1)


gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
canny = cv2.Canny(gray, 200, 300)

cv2.imshow('shjkgdh', canny)
gray = cv2.medianBlur(gray, 5)
circles = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT, 1, 20,
              param1=100,
              param2=30,
              minRadius=0,
              maxRadius=0)

print circles
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
    cv2.circle(img,(i[0],i[1]),i[2],(0,255,0),2)
    cv2.circle(img,(i[0],i[1]),2,(0,0,255),3)

cv2.imshow('circles', img)
k = cv2.waitKey(0)
if k == 27:
    cv2.destroyAllWindows()

你的代码运行得很好。问题出在您的
HoughCircles
阈值参数中

让我们试着从以下方面了解您正在使用的参数:

param1–第一个方法特定参数。如果是CV_HOUGH_梯度 ,它是传递到Canny()边缘的两个阈值中较高的阈值 探测器(较低的一个小两倍)

param2–第二个方法特定参数。万一 CV_HOUGH_梯度,它是圆的累加器阈值 中心处于检测阶段。越小越假 可以检测到圆圈。圆,对应于较大的 将首先返回累加器值

因此,正如您所见,HoughCircles函数在内部调用Canny边缘检测器,这意味着您可以在函数中使用灰色图像,而不是它们的轮廓

现在将
param1
减少到30,将
param2
减少到15,并在下面的代码中查看结果:

import cv2
import numpy as np

img = np.ones((200,250,3), dtype=np.uint8)
for i in range(50, 80, 1):
    for j in range(40, 70, 1):
        img[i][j]*=200

cv2.circle(img, (120,120), 20, (100,200,80), -1)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

circles = cv2.HoughCircles(gray, cv2.cv.CV_HOUGH_GRADIENT, 1, 20,
              param1=30,
              param2=15,
              minRadius=0,
              maxRadius=0)

print circles
circles = np.uint16(np.around(circles))
for i in circles[0,:]:
    cv2.circle(img,(i[0],i[1]),i[2],(0,255,0),2)
    cv2.circle(img,(i[0],i[1]),2,(0,0,255),3)

cv2.imshow('circles', img)

k = cv2.waitKey(0)
if k == 27:
    cv2.destroyAllWindows()

如果您没有让HoughCircles为您的明显圆圈提供像素级完美解决方案,那么您就没有正确使用它

你的错误是你试图自己手动调整超参数。那是行不通的。让计算机为您自动调整参数:

import numpy as np
import argparse
import cv2
import signal

from functools import wraps
import errno
import os
import copy

ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required = True, help = "Path to the image")
args = vars(ap.parse_args())

image = cv2.imread(args["image"])
orig_image = np.copy(image)
output = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

cv2.imshow("gray", gray)
cv2.waitKey(0)

circles = None

minimum_circle_size = 100      #this is the range of possible circle in pixels you want to find
maximum_circle_size = 150     #maximum possible circle size you're willing to find in pixels

guess_dp = 1.0

number_of_circles_expected = 1          #we expect to find just one circle
breakout = False

max_guess_accumulator_array_threshold = 100     #minimum of 1, no maximum, (max 300?) the quantity of votes 
                                                #needed to qualify for a circle to be found.
circleLog = []

guess_accumulator_array_threshold = max_guess_accumulator_array_threshold

while guess_accumulator_array_threshold > 1 and breakout == False:
    #start out with smallest resolution possible, to find the most precise circle, then creep bigger if none found
    guess_dp = 1.0
    print("resetting guess_dp:" + str(guess_dp))
    while guess_dp < 9 and breakout == False:
        guess_radius = maximum_circle_size
        print("setting guess_radius: " + str(guess_radius))
        print(circles is None)
        while True:

            #HoughCircles algorithm isn't strong enough to stand on its own if you don't
            #know EXACTLY what radius the circle in the image is, (accurate to within 3 pixels) 
            #If you don't know radius, you need lots of guess and check and lots of post-processing 
            #verification.  Luckily HoughCircles is pretty quick so we can brute force.

            print("guessing radius: " + str(guess_radius) + 
                    " and dp: " + str(guess_dp) + " vote threshold: " + 
                    str(guess_accumulator_array_threshold))

            circles = cv2.HoughCircles(gray, 
                cv2.cv.CV_HOUGH_GRADIENT, 
                dp=guess_dp,               #resolution of accumulator array.
                minDist=100,                #number of pixels center of circles should be from each other, hardcode
                param1=50,
                param2=guess_accumulator_array_threshold,
                minRadius=(guess_radius-3),    #HoughCircles will look for circles at minimum this size
                maxRadius=(guess_radius+3)     #HoughCircles will look for circles at maximum this size
                )

            if circles is not None:
                if len(circles[0]) == number_of_circles_expected:
                    print("len of circles: " + str(len(circles)))
                    circleLog.append(copy.copy(circles))
                    print("k1")
                break
                circles = None
            guess_radius -= 5 
            if guess_radius < 40:
                break;

        guess_dp += 1.5

    guess_accumulator_array_threshold -= 2

#Return the circleLog with the highest accumulator threshold

# ensure at least some circles were found
for cir in circleLog:
    # convert the (x, y) coordinates and radius of the circles to integers
    output = np.copy(orig_image)

    if (len(cir) > 1):
        print("FAIL before")
        exit()

    print(cir[0, :])

    cir = np.round(cir[0, :]).astype("int")

    for (x, y, r) in cir:
        cv2.circle(output, (x, y), r, (0, 0, 255), 2)
        cv2.rectangle(output, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)

    cv2.imshow("output", np.hstack([orig_image, output]))
    cv2.waitKey(0)
将numpy导入为np
导入argparse
进口cv2
输入信号
从functools导入包装
输入错误号
导入操作系统
导入副本
ap=argparse.ArgumentParser()
ap.add_参数(“-i”,“--image”,required=True,help=“图像路径”)
args=vars(ap.parse_args())
image=cv2.imread(args[“image”])
原始图像=np.复制(图像)
输出=image.copy()
灰色=cv2.CVT颜色(图像,cv2.COLOR\u BGR2GRAY)
cv2.imshow(“灰色”,灰色)
cv2.等待键(0)
圆圈=无
最小圆圈大小=100#这是以像素为单位的可能圆圈范围
最大圆圈大小=150#您希望以像素为单位找到的最大可能圆圈大小
猜测_dp=1.0
圈数预计=1#我们预计只会找到一个圈
断开=错误
max_guess_acculator_array_threshold=100#最小值为1,无最大值,(最大值300?)投票数量
#需要有资格找到一个圆。
circleLog=[]
猜测\累加器\数组\阈值=最大猜测\累加器\数组\阈值
当guess_accumulator_array_threshold>1且breakout==False时:
#从尽可能小的分辨率开始,找到最精确的圆,如果找不到,就慢慢变大
猜测_dp=1.0
打印(“重置猜测dp:+str(猜测dp))
而guess_dp<9和breakout==False:
猜测半径=最大圆大小
打印(“设置猜测半径:+str(猜测半径))
打印(圆圈为无)
尽管如此:
#如果您不这样做,HoughCircles算法就不足以独立运行
#准确知道图像中圆的半径(精确到3像素以内)
#如果你不知道半径,你需要大量的猜测和检查以及大量的后处理
#核实。幸运的是HoughCircles相当快,所以我们可以使用蛮力。
打印(“猜测半径:+str(猜测半径)+
和dp:“+str(guess_dp)+”投票阈值:”+
str(猜测\累加器\数组\阈值))
圆=cv2。霍夫圆(灰色,
cv2.cv.cv_HOUGH_梯度,
dp=猜测#累加器阵列的分辨率。
minDist=100,#圆圈中心的像素数应彼此相距,硬编码
参数1=50,
param2=猜测\累加器\数组\阈值,
minRadius=(猜测半径为3),#HoughCircles将查找最小尺寸的圆
maxRadius=(猜测半径+3)#HoughCircles将查找最大尺寸的圆
)
如果圆不是无:
如果len(圆[0])==预期的圆数:
打印(“圆的长度:+str(圆的长度)))
circleLog.append(copy.copy(圆圈))
打印(“k1”)
打破
圆圈=无
猜一猜半径-=5
如果半径小于40:
打破
猜测_dp+=1.5
猜测\u累加器\u数组\u阈值-=2
#返回具有最高累加器阈值的circleLog
#确保至少找到一些圆圈
对于circleLog中的cir:
#将圆的(x,y)坐标和半径转换为整数
输出=np.复制(原始图像)
如果(len(cir)>1):
打印(“之前失败”)
退出()
打印(cir[0,:])
cir=np.round(cir[0,:]).astype(“int”)
对于cir中的(x,y,r):
圆(输出,(x,y),r,(0,0,255),2)
矩形(输出,(x-5,y-5),(x+5,y+5),(0128255),-1)
cv2.imshow(“输出”,np.hstack([orig_图像,输出])
cv2.等待键(0)
上面的代码转换为:

对此:


有关此操作的更多信息,请参阅:

Ok,出于某些原因,它会突然在相当多的参数下工作。从昨天开始,我经历了所有的事情,但现在一切正常了。这对我来说没有多大意义,但好吧…霍夫圆有点。。在实践中很棘手。谢谢:)我展示了精明的结果,以便更好地了解HoughCircles实际使用的是什么。精明的结果看起来总是干净的