在不完美的圆形物体周围画圆圈

时间:2017-09-01 15:46:19

标签: python opencv image-processing

我有这个眼睛的图像,我想得到瞳孔的中心: Original Image

我使用以下代码将自适应阈值和laplacian应用于图像:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('C:\Users\User\Documents\module4\input\left.jpg',0)
image = cv2.medianBlur(img,5)

th = cv2.adaptiveThreshold(image,255,cv2.ADAPTIVE_THRESH_MEAN_C, 
cv2.THRESH_BINARY,11,2)

laplacian = cv2.Laplacian(th,cv2.CV_64F)

cv2.imshow('output', laplacian)
cv2.imwrite('C:\Users\User\Documents\module4\output\output.jpg', laplacian)

cv2.waitKey(0)
cv2.destroyAllWindows

,生成的图像如下所示:Resulting image by applying adaptive threshold

我想围绕较小的内圈绘制一个圆圈并获得它​​的中心。我尝试过使用轮廓和圆形霍夫变换,但它没有正确检测到图像中的任何圆圈。

这是我的圆形霍夫变换代码:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('C:\Users\User\Documents\module4\output\output.jpg',0)

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

circles = np.uint16(np.around(circles))
for i in circles[0,:]:
    # draw the outer circle
    cv2.circle(img,(i[0],i[1]),i[2],(255,255,0),2)
    # draw the center of the circle
    cv2.circle(img,(i[0],i[1]),2,(255,0,255),3)

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

以下是应用轮廓的代码:

import cv2
import numpy as np

img = cv2.imread('C:\Users\User\Documents\module4\output\output.jpg',0)

_, contours,hierarchy = cv2.findContours(img, 1, 2)

cnt = contours[0]

(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img = cv2.circle(img,center,radius,(0,255,255),2)

cv2.imshow('contour', img)

cv2.waitKey(0)
cv2.destroyAllWindows()

此代码的结果图像看起来像我应用自适应阈值的图像。如果有人能帮助我解决我的问题,我将非常感激。我已经坚持了一段时间了。另外,如果你们中的任何一个人能够建议一种更好的方法来探测除了这种方法之外的瞳孔中心,我也会非常感激。

3 个答案:

答案 0 :(得分:2)

尝试在过滤原始图像后应用边缘检测而不是共享,然后应用hough circle

答案 1 :(得分:1)

我的想法是像你一样使用霍夫变换。但另一种方法可能是像这样的模板匹配。这假设您知道图像中瞳孔的近似半径,您可以尝试构建模板。

import skimage
import numpy as np
import matplotlib.pyplot as plt

img = skimage.io.imread('Wjioe.jpg')

#just use grayscale, but you could make separate template for each r,g,b channel 
img = np.mean(img, axis=2)

(M,N) = img.shape
mm = M-20
nn = N-20
template = np.zeros([mm,nn])

## Create template ##

#darkest inner circle (pupil)
(rr,cc) = skimage.draw.circle(mm/2,nn/2,4.5, shape=template.shape)
template[rr,cc]=-2

#iris (circle surrounding pupil)
(rr,cc) = skimage.draw.circle(mm/2,nn/2,8, shape=template.shape)
template[rr,cc] = -1

#Optional - pupil reflective spot (if centered)
(rr,cc) = skimage.draw.circle(mm/2,nn/2,1.5, shape=template.shape)
template[rr,cc] = 1

plt.imshow(template)

normccf = skimage.feature.match_template(img, template,pad_input=True)

#center pixel
(i,j) = np.unravel_index( np.argmax(normccf), normccf.shape)

plt.imshow(img)
plt.plot(j,i,'r*')

normccf

答案 2 :(得分:0)

您为灰度图像定义了3通道颜色。根据我的测试,它只会读取该元组中的第一个值。因为其他颜色中的第一个值(在中间代码中)以255开头,所以它会绘制一个完整的白色圆圈,因为最后一个颜色中的第一个值(在上一个代码中)以0开头,它会绘制一个完整的黑色圆圈,你看不到。
只需将您的颜色值更改为1通道颜色(0到255之间的int),您就可以了。