python - 如何检测填充了哪些圆圈+ OpenCV + Python

原文 标签 python opencv numpy image-processing circleimage

How to detect which circles are filled + OpenCV + Python

I am trying to develop a code to identify filled circle between number of empty circles.

I have already identified each circle in center ordinates. How to detect which circle is empty & Which circle is filled?

I have already develop this code

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

These are my input & output images for above code.. enter image description here enter image description here

Thanks in advance..

Answer

Steps involved :

  • Get the minimum circle radius from the third col of circles info from cv2.HoughCircles.

  • Use 2D convolution on the inverted image, with the intention of finding blackened-blobs that would have greater value than the background and the whitened-blobs upon convolution.

  • Get the convoluted output at the circle centers again obtained in circles as the third col. Use a half threshold to decide between that blob was originally blackened or whitened.

The edited part of the implementation -

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

Output -

enter image description here

To be more precise, since we are dealing with circles, we could use circular mask as kernel. Thus, to bring in that criteria -

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)

翻译

我正在尝试开发代码以识别空圆之间的实心圆。

我已经确定了中心坐标中的每个圆。
如何检测哪个圆是空的,哪个圆是实心的?

我已经开发了这段代码

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

提前致谢..
最佳答案
涉及的步骤:


circlescv2.HoughCircles信息的第三列获取最小圆半径。
在倒置的图像上使用2D卷积,目的是找到卷积后比背景和blackened-blobs具有更大价值的whitened-blobs
再次获得在circles中获得的圆心的卷积输出作为第三列。使用半个阈值来确定Blob最初是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)
相关推荐

python - 是否可以更改当地人的命令?

python - 为Python2和Python3编写Unicode正则表达式

python - pip安装tesserocr失败,并显示错误“ tesserocr的建筑轮失败”

python - webbrowser python在同一选项卡中打开新的URL。这行得通吗?

python - 使用Python进行轨迹聚类/聚合

python - 使用model.fit_generator时keras val非常慢

python - 在Python 2.7中模拟布尔__bool__协议方法

python - 为什么“ nparray.tolist()”占用了这么多空间?

python - 减少(倍数)熊猫

python - 具有不同形状的Tensorflow元组