边缘模糊的OpenCV圆/椭圆检测

时间:2018-12-20 22:33:43

标签: opencv edge-detection

如何在下图中定位瞳孔(眼球中的小圆圈)并计算瞳孔面积。我尝试使用霍夫圆检测和椭圆拟合在具有各种阈值的轮廓上进行拟合,但是这些幼稚的方法都无法很好地工作。

特别是,HoughCircle检测在许多噪声中完全丢失,并且经过修剪的椭圆检测通常最终会产生较大的圆圈。

而且我不确定如何在不手动调整轨迹栏的情况下确定功能阈值。有人可以给我一些有关如何准确执行此操作的指导吗?

眼球样本

1 个答案:

答案 0 :(得分:-1)

简单的图像处理过程应该可以帮助您实现目标。

首先以灰度加载图像。我认为Otsu阈值方法足够健壮,可以提取眼睛的瞳孔区域。需要额外的形态处理以消除噪声和未填充区域

enter image description here

然后使用连通分量分析,我们可以隔离瞳孔区域以进行进一步处理。

enter image description here

有了这个区域,我们可以通过用原始区域减去一个膨胀区域来获得边缘,如下所示。

enter image description here

最后,我们可以运行圆形拟合或椭圆拟合算法来获得相应的形状,

enter image description here

圆形拟合显示为红色,椭圆形显示为绿色。两者都返回相同的中心位置,尽管形状略有不同。

这是使用的代码。我缩小图像以加快处理过程,但在使用原始大小的情况下也可以使用。

import cv2
import numpy as np

img = cv2.imread('eye.jpg',0)

small_img = cv2.resize(img,(0,0),fx = 0.25, fy = 0.25)
r,c = small_img.shape
# Threshold objs
_, thresh = cv2.threshold(small_img,0,255,cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# Morphological close process to cluster nearby objects
bin_img = cv2.dilate(thresh, None,iterations = 5)
bin_img = cv2.erode(bin_img, None,iterations = 5)

# Analyse connected components
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(bin_img)

# Find circle center and radius
# Radius calculated by averaging the height and width of bounding box
bin_eye = np.zeros((r,c))
cnt_label = labels[r/2,c/2]
bin_eye[labels == cnt_label] = 255
area = stats[cnt_label][4]
radius = np.sqrt(area / np.pi)
cnt_pt = ((centroids[cnt_label][0]),(centroids[cnt_label][1]))

# fit ellipse
bin_eye_large = cv2.dilate(bin_eye, None,iterations = 1)

# Get ellipse edge
edge_eye = bin_eye_large - bin_eye

# extract location points for fitting
ellip_pts = np.where(edge_eye > 0)
ellip_pts = np.transpose(ellip_pts)
temp = np.copy(ellip_pts[:,0])
ellip_pts[:,0] = ellip_pts[:,1]
ellip_pts[:,1] = temp

# fit ellipse
ellip = cv2.fitEllipse(ellip_pts)


# Display final result
edges_color = cv2.cvtColor(small_img,cv2.COLOR_GRAY2BGR)
cv2.circle(edges_color,(int(cnt_pt[0]),int(cnt_pt[1])),int(radius),(0,0,255),1)
cv2.circle(edges_color,(int(cnt_pt[0]),int(cnt_pt[1])),5,(0,0,255),1)
cv2.ellipse(edges_color,ellip, (0,255,0))
cv2.circle(edges_color,(int(ellip[0][0]),int(ellip[0][1])),5,(0,255,0),1)

cv2.imshow('edges_color',edges_color)
cv2.imshow('bin_img',bin_img)
cv2.imshow('eye_label',bin_eye)
cv2.imshow('eye_edge',edge_eye)

cv2.waitKey(0)
相关问题