使用OpenCV和Python检测眼睛

  |   0 评论   |   0 浏览   |   给我丶鼓励

今天,我们将学习如何借助称为霍夫变换的技术来检测图像中的直线和圆。

什么是霍夫空间?

在开始对图像应用霍夫变换之前,我们需要了解霍夫空间是什么,我们将通过示例的方式来学习。

参数空间

当我们处理图像时,我们可以想象图像是在某些 x 和 y 坐标上的 2d 矩阵,在此之下,一条线可以描述为 y = mx + b

参数空间

但是在参数空间(我们将其称为霍夫空间)中,我可以代表与 m vs 相同的线 b,因此图像空间上线的特征将是 m-b 霍夫空间中该位置的单点。

霍夫空间

但是,我们有一个问题,因为 y = mx + b,我们不能代表垂直线,因为斜率是无限的。因此,我们需要一种更好的参数化方法,即极坐标(rho 和 theta)。

霍夫空间

  • rho:描述直线到原点的距离
  • theta:描述与水平面的夹角

线极坐标

但是,一个非常重要的发现是,当我们围绕一条线取多个点并转换为霍夫空间时,会发生什么。

霍夫空间中的点和线关系

图像空间上的单个点转换为霍夫空间上的曲线,其特殊之处在于,图像空间上一条线之间的点将由具有单个接触点的多条曲线表示。

这将是我们的目标,找到一组曲线相交的点。

什么是霍夫变换?

霍夫变换是一种特征提取方法,用于检测图像中的简单形状,例如圆形,直线等。

“简单”特性是根据参数的形状表示得出的。“简单”形状将仅由几个参数表示,例如,一条线可以由其斜率和截距表示,或者可以由 x,y 和半径表示。

在我们的直线示例中,霍夫变换将负责处理图像上的点并计算霍夫空间中的值。

进行转换并随后找到相交曲线的算法有点复杂,因此不在本文讨论范围之内。但是,我们将看一下该算法的实现,它是 OpenCV 库的一部分。

使用 OpenCV 检测线

在 OpenCV 中,使用 HoughLinesHoughLinesP 概率霍夫变换实现了使用霍夫变换的行检测。我们将专注于后者。

该函数需要以下参数:

  • image:8 位单通道二进制源图像。该图像可以通过该功能进行修改。
  • lines:行的输出向量。每条线由 4 个元素的向量(x_1,y_1,x_2,y_2)表示,其中(x_1,y_1)和(x_2,y_2)是每个检测到的线段的终点。
  • rho:累加器的距离分辨率(以像素为单位)。
  • theta:累加器的角度分辨率(以弧度为单位)。
  • threshold:累加器阈值参数。仅返回那些获得足够投票的行
  • minLineLength:最小行长。短于此的线段将被拒绝。
  • maxLineGap:同一线上的点之间允许链接的最大间隙。

太复杂?一个例子更容易:

# Read image 
img = cv2.imread('lanes.jpg', cv2.IMREAD_COLOR)
# Convert the image to gray-scale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Find the edges in the image using canny detector
edges = cv2.Canny(gray, 50, 200)
# Detect points that form a line
lines = cv2.HoughLinesP(edges, 1, np.pi/180, max_slider, minLineLength=10, maxLineGap=250)
# Draw lines on the image
for line in lines:
    x1, y1, x2, y2 = line[0]
    cv2.line(img, (x1, y1), (x2, y2), (255, 0, 0), 3)
# Show result
cv2.imshow("Result Image", img)

结果如下:

线路检测示例

非常重要的一点是,我们实际上使用仅边缘图像作为 Hough 变换的参数,否则该算法将无法按预期工作。

使用 OpenCV 检测圈子

该过程与行的过程大致相同,除了这次我们将使用与 OpenCV 库不同的函数。我们将使用 now HoughCircles,它接受以下参数:

  • image:8 位单通道灰度输入图像。
  • circles:找到的圆的输出向量。每个向量都被编码为 3 元素浮点向量(x,y,radius)。
  • circle_storage:在 C 函数中,这是一个存储器存储,其中将包含找到的圆的输出序列。
  • method:使用的检测方法。当前,唯一实现的方法是 CV_HOUGH_GRADIENT,基本上是 21HT
  • dp:累加器分辨率与图像分辨率的反比。例如,如果 dp = 1,则累加器具有与输入图像相同的分辨率。如果 dp = 2,则累加器的宽度和高度是其一半。
  • minDist:检测到的圆心之间的最小距离。如果参数太小,则除了真实的圆圈之外,还可能会错误地检测到多个邻居圆圈。如果太大,可能会错过一些圈子。
  • param1:第一个方法特定的参数。在 CV_HOUGH_GRADIENT 的情况下,它是传递给 Canny()边缘检测器的两个阈值中的较高阈值(较低的阈值小两倍)。
  • param2:第二个方法特定的参数。在 CV_HOUGH_GRADIENT 的情况下,它是检测阶段圆心的累加器阈值。它越小,可能会检测到更多的假圆圈。与较大的累加器值相对应的圆将首先返回。
  • minRadius:最小圆弧半径。
  • maxRadius:最大圆半径。

请记住,参数必须有所不同,因为我们无法用与用于线相同的参数化描述圆,而是需要使用像的方程 (x - x0)^^2 + (y - y0)^^2 = r^^2

和代码:

# Read image as gray-scale
img = cv2.imread('circles.png', cv2.IMREAD_COLOR)
# Convert to gray-scale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Blur the image to reduce noise
img_blur = cv2.medianBlur(gray, 5)
# Apply hough transform on the image
circles = cv2.HoughCircles(img_blur, cv2.HOUGH_GRADIENT, 1, img.shape[0]/64, param1=200, param2=10, minRadius=5, maxRadius=30)
# Draw detected circles
if circles is not None:
    circles = np.uint16(np.around(circles))
    for i in circles[0, :]:
        # Draw outer circle
        cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
        # Draw inner circle
        cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 3)

请注意,与之前的示例相比,此处未应用任何边缘检测功能。这是因为该函数 HoughCircles 具有内置的 canny 检测。

结果:

圆检测示例

结论

霍夫变换是一种用于检测图像中简单形状的出色技术,它具有多种应用,从医学应用(例如 X 射线,CT 和 MRI 分析)到自动驾驶汽车。


标题:使用OpenCV和Python检测眼睛
作者:给我丶鼓励
地址:https://blog.doiduoyi.com/articles/1591799702840.html

评论

发表评论