2017-04-15 337 views
4

我正在嘗試開發一個代碼來識別空圓圈數量之間的實心圓。如何檢測填充的圓圈+ OpenCV + Python

我已經確定了中心座標中的每個圓。 如何檢測哪個圓圈是空的&填充了哪個圓圈?

我已經開發這個代碼

import numpy as np 
import cv2 
import math 

img = cv2.imread("small.jpg",0) 
img = cv2.medianBlur(img,5) 
cimg = cv2.cvtColor(img,cv2.COLOR_GRAY2BGR) 

circles =cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,60,param1=50,param2=30,minRadius=0,maxRadius=0) 

circles = np.uint16(np.around(circles)) 
counter=0 
correctC=[] 
xC=[] 
yC=[] 

for i in circles[0,:]: 
    #cv2.circle(cimg,(i[0],i[1]),i[2],(0,255,0),2) 
    #cv2.circle(cimg,(i[0],i[1]),2,(0,0,255),2) 
    cv2.putText(cimg,str(i[0])+","+str(i[1])+","+str(i[2]),(i[0],i[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.3,(255,0,0),1,cv2.LINE_AA) 
    correctC.append((i[0],i[1],i[2])) 
    xC.append(i[0]) 
    yC.append(i[1]) 
    counter+=1 

print "Circle Count is : " + str(counter) 

xCS=sorted(xC) 
yCS=sorted(yC) 
xS=sorted(correctC, key=lambda correctC:correctC[0]) 

q1=sorted(xS[:4],key=lambda correctC: correctC[1]) 
q2=sorted(xS[4:8],key=lambda correctC: correctC[1]) 
q3=sorted(xS[8:12],key=lambda correctC: correctC[1]) 
q4=sorted(xS[12:16],key=lambda correctC: correctC[1]) 
q5=sorted(xS[16:20],key=lambda correctC: correctC[1]) 
q6=sorted(xS[20:24],key=lambda correctC: correctC[1]) 
q7=sorted(xS[24:28],key=lambda correctC: correctC[1]) 
q8=sorted(xS[28:32],key=lambda correctC: correctC[1]) 
q9=sorted(xS[32:],key=lambda correctC: correctC[1]) 

sortedTmp=[q1,q2,q3,q4,q5,q6,q7,q8,q9] 
sorted=[] 

for i in sortedTmp: 
    for j in i: 
     sorted.append(j) 

for i in range(36): 
    cv2.putText(cimg,str(i),(sorted[i][0],sorted[i][1]), cv2.FONT_HERSHEY_SIMPLEX, 1,(255,0,0),3,cv2.LINE_AA) 

cv2.imshow('detected circles',cimg) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

這些是參與我的輸入&輸出圖像上面代碼.. enter image description here enter image description here

在此先感謝..

+1

使用'numpy.count()'計算每個圓圈中存在的黑色像素的數量。如果它很高=>它是一個實心圓或其他空心圓 –

回答

1

步驟:

  • cv2.HoughCircles獲取第三列circles信息的最小圓半徑。

  • 使用2D卷積反轉圖像上,以尋找blackened-blobs,將有比背景更大的價值和whitened-blobs卷積時的意圖。

  • 獲得圓圈中心的複雜輸出,該圓心再次獲得circles作爲第三列。使用半閾值來決定該斑點最初是blackened還是whitened

的執行編輯的部分 -

from scipy.signal import convolve2d 

sortedTmp=[q1,q2,q3,q4,q5,q6,q7,q8,q9] 
sorted1=[] 

for i in sortedTmp: 
    for j in i: 
     sorted1.append(j) 

sorted_circles = np.array(sorted1) 

circle_radius = sorted_circles[...,-1].min() 
kernel = np.ones((2*circle_radius,2*circle_radius),dtype=int) 
out0 = convolve2d(255-img, kernel,'same') 
detected_vals = out0[sorted_circles[...,1], sorted_circles[...,0]] 
detected_vals -= detected_vals.min() 
mask = detected_vals>detected_vals.max()/2   

for i in range(36): 
    cv2.putText(cimg,str(i),(sorted1[i][0],sorted1[i][1]), cv2.FONT_HERSHEY_SIMPLEX, 1,(255,0,0),3,cv2.LINE_AA) 
    if mask[i]==1: 
     cv2.putText(cimg,"B",(sorted1[i][0],sorted1[i][1]-28), cv2.FONT_HERSHEY_SIMPLEX, 0.5,(255,0,0),1,cv2.LINE_AA) 
    else: 
     cv2.putText(cimg,"W",(sorted1[i][0],sorted1[i][1]-28), cv2.FONT_HERSHEY_SIMPLEX, 0.5,(255,0,0),1,cv2.LINE_AA) 

cv2.imshow('detected circles',cimg) 
cv2.waitKey(0) 
cv2.destroyAllWindows() 

輸出 -

enter image description here

爲了更準確,因爲我們正在處理的圓,我們可以使用圓形面具作爲核心。因此,要引入這個標準 -

def circle_mask(r) : #r - radius of circular mask 
    y,x = np.ogrid[-r:r+1, -r:r+1] 
    return x*x + y*y <= r*r 

R = 1+2*((circle_radius-1)//2) # Get odd number for radius 
kernel = circle_mask(R).astype(int)