2017-09-01 125 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之間的整數),您就會好起來的。