2017-09-01 97 views
2

我有一个眼睛的这个图像,我想要得到的瞳孔的中心: Original Image绘制圆周围不完善圆形物体

我使用此代码施加自适应阈值以及拉普拉斯到图像:

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

我想提请各地的小内圆了一圈,并得到它的中心。我试过使用轮廓和圆形hough变换,但它不能正确检测图像中的任何圆圈。

这是改变我对圆霍夫代码:

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

生成的验证码的图片完全相同貌似其中我应用的图像自适应阈值。如果有人能帮我解决我的问题,我将不胜感激。我一直坚持这一段时间。此外,如果你们中的任何人都可以提出更好的方法来检测除了这种方法之外的瞳孔中心,我也会非常感激。

回答

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

+0

我很抱歉,但我不是很熟悉使用skimage。我仍然需要研究它,但这种方式似乎非常好。我有一个问题,但这种方法是否适用于像这样的所有眼睛图像?眼睛的位置以及图像的大小不会改变,但我计划使用此代码来检测摄像机拍摄的图像中不同人的瞳孔。如果我只是指定瞳孔半径的“安全”近似值,你认为它会起作用吗? – Swagayema

+0

对于不同尺寸的瞳孔/虹膜的不同眼睛图像,它应该可以很好地工作。但是,您可能需要调整模板,例如,如果瞳孔中没有相机闪光反射,请移除中心的亮点。如果它适合你,也请接受/提出答案。 –

+0

也是各个部分的半径。但只要大部分可见,眼睛在图像中的位置应该不重要。 –

-1

尝试应用边缘检测,而不是持股原始图像的滤波之后,然后应用霍夫圆

0

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