2015-08-29 2 views
4

Я читал много о преобразовании Circular Hough в переполнении стека, но мне, кажется, что-то не хватает. Я написал программу, которая должна обнаруживать круги цели «Бычье глаза». Однако даже после игры с параметрами алгоритм довольно плох - он игнорирует большинство кругов и один раз находит кружок, но, похоже, «блуждает». Я даже попытался применить «Unsharp Mask» безрезультатно. Я добавил свой код, изображение, с которого я начал, и выход. Надеюсь, кто-то может указать мне в правильном направлении.Циркулярное преобразование Hough пропускает круги

import cv2 
import cv2.cv as cv 
import numpy as np 
import math 
# Load Image 
img = cv2.imread('circles1.png',0) 
# Apply Unsharp Mask 
tmp = cv2.medianBlur(img,5) 
img = cv2.addWeighted(img,1.5,tmp,-0.5,0) 
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) 

# Hough Transform 
circles = cv2.HoughCircles(img,cv.CV_HOUGH_GRADIENT,1,5, 
          param1=100,param2=100,minRadius=0,maxRadius=0) 

circles = np.uint16(np.around(circles)) 

# Go over circles, eliminating the ones that are not cocentric enough 
height, width = img.shape 
center = (width/2,height/2) 
for i in circles[0,:]: 
    # draw the outer circle 
    if math.sqrt((center[0]-i[0])**2 + (center[1]-i[1])**2) < 15: 
     cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),1) 
     # draw the center of the circle 
     cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3) 

cv2.imshow('detected circles',cimg) 

cv2.waitKey(0) 
cv2.destroyAllWindows() 

Краткое объяснение: Я загрузить изображение, применить Unsharp Mask, используйте Хока Transfrom для обнаружения кругов, затем нарисуйте круги, близкие к центру (я обнаружил, что другие круги ложные круги).

Я пробовал играть с параметрами, и это лучшее, что я получил. Я чувствую, что это довольно простая проблема, которая меня раздражает. Я предлагаю любую помощь.

Моего вход изображение:

Input image

Мой вывод изображение:

Output image

+0

http://answers.opencv.org/question/31246/houghcircles-seems-powerless-when-dealing-with-concentric-circles/ – Miki

+0

Вам придется перебирать 'cv2.HoughCircles' несколько раз, изменяя' minRadius' и 'maxRadius', пока вы не обнаружите все круги. – rayryeng

ответ

4

Как я уже говорил в моем комментарии, вам необходимо выполнить последовательные итерации cv2.HoughCircles для различного диапазона радиусов, чтобы вы получили все круги. С тем, как работает Circular Hough Transform, указание минимального и максимального радиуса, который имеет довольно большой диапазон, будет неточным, а также будет медленным. Они не говорят вам об этом в документации, но и для циркулярной преобразования Хока, чтобы успешно работать, следующие две вещи должны быть действительно:

maxRadius < 3*minRadius 
maxRadius - minRadius < 100 

С выше, слепо делая минимальный радиус очень мал и максимальный радиус очень большой не даст вам больших результатов. Таким образом, вы можете начать с ... скажем ... radius=1, а затем итерации до radius=300 с шагом 20. Между каждой порцией 20 запустите cv2.HoughCircles и обновите свое изображение этими контурами.

Для этого требуется очень малое изменение кода. Кстати, я удалил нерезкое маскирование, потому что у меня были плохие результаты. Я также изменил несколько параметров в cv2.HoughCircles немного, чтобы получить эту работу как можно лучше данную ситуацию:

import cv2 
import cv2.cv as cv 
import numpy as np 
import math 
# Load Image 
img = cv2.imread('circles1.png',0) 
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) 

# Specify different radii 
radii = np.arange(0,310,10) 

# For each pair of radii... 
for idx in range(len(radii)-1): 
    # Get the minimum and maximum radius 
    # Note you need to add 1 to each minimum 
    # as the maximum of the previous pair covers this new minimum 
    minRadius = radii[idx]+1 
    maxRadius = radii[idx+1] 

    # Hough Transform - Change here 
    circles = cv2.HoughCircles(img,cv.CV_HOUGH_GRADIENT,1,5, 
           param1=25,param2=75,minRadius=minRadius,maxRadius=maxRadius) 

    # Skip if no circles are detected - Change here 
    if circles is None: 
     continue 

    circles = np.uint16(np.around(circles)) 

    # Go over circles, eliminating the ones that are not cocentric enough 
    height, width = img.shape 
    center = (width/2,height/2) 
    for i in circles[0,:]: 
     # draw the outer circle 
     if math.sqrt((center[0]-i[0])**2 + (center[1]-i[1])**2) < 15: 
      cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),1) 
      # draw the center of the circle 
      cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),3) 

cv2.imshow('detected circles',cimg) 

cv2.waitKey(0) 
cv2.destroyAllWindows() 

Я получаю эту цифру:

enter image description here

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


Однако, я бы не рекомендовал использовать cv2.HoughCircles здесь. Могу я предложить вместо этого использовать cv2.findContours? Это находит все контуры изображения. В этом случае это будут черные круги.Тем не менее, вы должны полностью изменить изображение, потому что cv2.findContours принимает ненулевые пиксели объекта пикселей, так что мы можем вычесть 255 из изображения при условии типа np.uint8:

# Make copy of original image 
cimg2 = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) 

# Find contours 
contours,_ = cv2.findContours(255 - img, cv2.RETR_LIST, cv.CV_CHAIN_APPROX_NONE) 

# Draw all detected contours on image in green with a thickness of 1 pixel 
cv2.drawContours(cimg2, contours, -1, color=(0,255,0), thickness=1) 

# Show the image 
cv2.imshow('detected circles', cimg2) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

Это то, что я получаю:

enter image description here

+1

Большое спасибо. Это действительно странно, что они не упоминают об этом в документах, но да, проблема в том, что hough не может обрабатывать круговые круги. Это решило проблему для меня. – Bloodworth

+0

Нет проблем. Пожалуйста, подумайте о том, чтобы принять мой ответ, если я помог вам, и у вас больше нет вопросов. Это можно сделать, щелкнув значок галочки под стрелками вверх и вниз в верхней части моего сообщения влево. Огромное спасибо! – rayryeng

+1

Очень приятно объяснил (+1) –

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