2017-04-15 664 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)