簡體   English   中英

圓形霍夫變換錯過了圓圈

[英]Circular Hough Transform misses circles

我已經閱讀了很多關於Stack Overflow上的Circular 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()

快速解釋:我加載圖像,應用USM銳化,使用Hough Transfrom檢測圓圈,然后繪制靠近中心的圓圈(我發現其他圓圈是假圓圈)。

我試着玩參數,這是我得到的最好的。 我覺得這是一個足夠簡單的問題,讓我得以緩解。 我贊美任何幫助。

我的輸入圖片:

輸入圖像

我的輸出圖片:

輸出圖像

正如我在評論中提到的,你需要為不同的半徑范圍運行cv2.HoughCircles連續迭代,以確保你得到所有的圓。 通過循環霍夫變換的工作方式,指定具有相當大范圍的最小和最大半徑將是不准確的並且也將是慢的。 他們沒有在文檔中告訴你,但是為了使Circular Hough Transform能夠成功運行,以下兩件事需要有效:

maxRadius < 3*minRadius
maxRadius - minRadius < 100

有了上述,盲目地使最小半徑非常小,最大半徑非常大,不會給你帶來很好的效果。 因此,你可以做的是從...說... radius=1 ,然后以20為步長迭代到radius=300在每個20塊之間,運行cv2.HoughCircles並用這些輪廓更新你的圖像。

這樣做只需要對代碼進行很少的修改。 順便說一句,我刪除了不清晰的掩蓋它,因為我的結果很糟糕。 我還稍微更改了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()

我得到這個數字:

在此輸入圖像描述

不幸的是,它並不完美,因為它沒有檢測到所有的圓圈。 你必須使用cv2.HoughCircles函數,直到你得到好的結果。


但是,我不建議在這里使用cv2.HoughCircles 我可以建議使用cv2.findContours嗎? 這可以找到圖像中的所有輪廓。 在這種情況下,這些將是黑色圓圈。 但是,您需要反轉圖像,因為cv2.findContours假設非零像素是對象像素,因此我們可以假設np.uint8類型從圖像中減去255:

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

這就是我得到的:

在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM