2014-10-08 2 views
3

Я пытаюсь использовать обнаружение круга OpenCV (Hough) для обнаружения кругов. Я создал сплошной круг на черном фоне, пытался играть с параметрами, использовал размытие и все, но я просто не могу найти что-либо.Обнаружение круга HoughCircles с использованием opencv и python-

Любые идеи, предложения и т. Д. Были бы замечательными, спасибо!

мой текущий код-то вроде этого:

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

Хорошо, по какой-то причине он неожиданно работает с множеством параметров. Я прошел через все, что было вчера, без работы, но теперь это так. Это не имеет для меня никакого смысла, но хорошо ... – Shin

+0

Шумные круги немного ... сложно, на практике. –

ответ

8

Ваш код работает просто отлично. Проблема заключается в ваших пороговых параметрах HoughCircles.

Давайте попробуем понять параметры, которые вы используете из OpenCV Docs:

param1 - Первый метод конкретного параметра. В случае CV_HOUGH_GRADIENT это более высокий порог двух, прошедших с детектора Canny() (нижний в два раза меньше).

param2 - Второй параметр, специфичный для конкретного метода. В случае CV_HOUGH_GRADIENT это порог аккумулятора для окружности центров на этапе обнаружения. Чем меньше это, тем больше обнаруживаются круги . Круги, соответствующие максимальным значениям аккумулятора , будут возвращены первыми.

Таким образом, как вы можете видеть, функция HoughCircles внутри функции вызывает детектор края Canny, это означает, что вы можете использовать серое изображение в функции вместо своих контуров.

Теперь уменьшить param1 до 30 и до 15 param2 и увидеть результаты в коде, который следующим образом:

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

+0

Спасибо :) Я показал хитрые результаты, чтобы получить лучшее представление о том, с чем он работает HoughCircles. Каннильные результаты всегда выглядели чистыми и тем же самым, что, вероятно, вызывало большую часть моей путаницы. Каким-то образом мне удалось всегда использовать параметры, которые не соответствовали даже тем, что я тестировал довольно много разных параметров. Поскольку canny изображение похоже на рабочие и неработающие параметры, я до сих пор не уверен, почему некоторые параметры работают, а другие нет. – Shin

+0

+1 Но мне интересно, как выглядит исходное изображение. – karlphillip

+0

Как это работает с maxRadius = 0? Несомненно, это ограничило бы появление каких-либо кругов? – ComputerScientist

0

Если вы не получаете 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) 

Приведенный выше код преобразует: Original

Для этого:

HoughCircles

Для получения дополнительной информации о что это делает, см .: https://stackoverflow.com/a/46500223/445131

Смежные вопросы