在计算机视觉和图像处理领域,从图像中提取有意义的特征至关重要。这些特征是各种下游任务(如目标检测和分类)的关键输入。寻找这些特征的方法有很多。最简单的方法是计算像素。但在 OpenCV 中,有许多例程可以帮助您从图像中提取特征。在这篇文章中,您将了解 OpenCV 如何帮助您找到一些高级特征。
完成本教程后,您将了解:
- 可以从图像中提取角点和边缘
- OpenCV 中用于提取角点和边缘的常见算法有哪些?
通过我的书《OpenCV 机器学习》启动您的项目。它提供了带有可用代码的自学教程。
让我们开始吧。

OpenCV 中的图像特征提取:边缘和角点
照片作者:Michael Barth,部分权利保留。
概述
这篇博文分为三部分;它们是:
- 理解图像特征提取
- OpenCV 中的 Canny 边缘检测
- OpenCV 中的 Harris 角点检测
先决条件
本教程假设您已熟悉以下内容:
理解图像特征提取
图像特征提取涉及识别和表示图像中的独特结构。读取图像的像素当然是一种方式。但这是一种低级特征。图像的高级特征可以是边缘、角点,甚至是更复杂的纹理和形状。
特征是图像的特征。通过这些独特的特征,您或许能够区分一张图像与另一张图像。这是计算机视觉的第一步。通过提取这些特征,您可以创建比仅仅是图像像素更紧凑、更有意义的表示。它有助于进一步的分析和处理。
接下来,您将学习两种基本但非常常见的特征提取算法。它们都以 numpy 数组的形式返回基于像素的分类。
OpenCV 中的 Canny 边缘检测
多年来,图像特征提取的算法已经开发了很多。它们不是机器学习模型,而是更接近确定性算法。这些算法都针对特定的特征。
OpenCV 提供了丰富的图像特征提取工具和函数。让我们从第一个开始:Canny 边缘检测。
在图像中查找线条可能是最简单的特征提取。其目标是识别哪个像素位于边缘上。边缘定义为像素强度的梯度。换句话说,如果存在突变的颜色变化,则认为它是边缘。但还有更多细节,因此会排除噪声。
让我们看下面的图像,并将其保存为本地目录中的image.jpg
查找和说明边缘的示例如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import cv2 import numpy as np # 加载图像 img = cv2.imread('image.jpg') # 转换为灰度 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 使用 Canny 方法检测边缘 edges = cv2.Canny(gray, 150, 300) # 显示带有角点的图像 img[edges == 255] = (255,0,0) cv2.imshow('Canny Edges', img) cv2.waitKey(0) cv2.destroyAllWindows() |
在上文中,图像被转换为灰度,然后调用cv2.Canny()
函数。许多特征提取算法都需要灰度图像,因为许多算法都是为处理单个颜色通道而设计的。
cv2.Canny()
函数的参数接受两个数值,分别代表最小和最大阈值。它们用于 **滞后阈值处理** 以将像素合并成边缘。最大阈值越高,最终结果中保留的边缘就越强。然而,最小阈值越高,您会看到更多的“断开的边缘”返回。
此函数返回一个与图像像素维度匹配的 numpy 数组,其值为 0(不在边缘上)或 255(在边缘上)。上面的代码将这些像素涂成了蓝色。结果如下

Canny 边缘检测结果
原始照片作者: Gleren Meneghin,部分权利保留。
您应该在上面的蓝色线条中看到标出的门窗,以及勾勒出的砖块。您可以调整这两个阈值以查看不同的结果。
OpenCV 中的 Harris 角点检测
Harris 角点检测是一种用于识别图像中强度显著变化的常用方法,这些变化通常对应于物体的角点。OpenCV 提供了该技术的简单而高效的实现,使我们能够检测出作为图像分析和匹配突出特征的角点。
从图像中提取角点可以分为三个步骤
- 将图像转换为灰度,因为 Harris 角点检测算法仅适用于单个颜色通道
- 运行
cv2.cornerHarris(image, blockSize, ksize, k)
并为每个像素获得一个分数 - 通过将分数与整个图像的最大值进行比较来识别哪个像素是角点
cornerHarris()
函数的参数包括邻域大小blockSize
和核大小ksize
。两者都是小的正整数,但后者必须是奇数。最后一个参数k
是一个正浮点值,用于控制角点检测的灵敏度。过大的值会导致算法将角点误判为边缘。您可能需要试验其值。
以下是一个示例代码,对上述同一图像运行 Harris 角点检测
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import cv2 import numpy as np # 加载图像 img = cv2.imread('image.jpg') # 转换为灰度 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 使用 Harris 方法检测角点 dst = cv2.cornerHarris(gray, 3, 5, 0.1) # 创建角点位置的布尔位图 corners = dst > 0.05 * dst.max() # 从布尔位图中找到坐标 coord = np.argwhere(corners) # 在坐标上绘制圆圈以标记角点 for y, x in coord: cv2.circle(img, (x,y), 3, (0,0,255), -1) # 显示带有角点的图像 cv2.imshow('Harris Corners', img) cv2.waitKey(0) cv2.destroyAllWindows() |
生成的图像将如下所示

Harris 角点检测结果
原始照片作者: Gleren Meneghin,部分权利保留。
红点是由上面 for 循环中的cv2.circle()
函数绘制的。它们仅用于说明。关键思想是,该算法为图像的每个像素提供一个分数,以表明其被认为是角点、边缘或“平坦”(即两者都不是)的程度。您需要通过将分数与整个图像中的最大值进行比较来控制结论的灵敏度,即在这一行:
1 2 |
corners = dst > 0.05 * dst.max() |
结果是一个布尔 numpy 数组corners
,然后使用np.argwhere()
函数将其转换为坐标数组。
从上图可以看出,Harris 角点检测并不完美,但如果角点足够明显,它就可以被检测出来。
想开始学习 OpenCV 机器学习吗?
立即参加我的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
书籍
- 使用 Python 精通 OpenCV 4, 2019.
网站
- OpenCV,https://opencv.ac.cn/
- OpenCV 特征检测和描述,https://docs.opencv.ac.cn/4.x/db/d27/tutorial_py_table_of_contents_feature2d.html
- OpenCV Canny 边缘检测,https://docs.opencv.ac.cn/4.x/da/d22/tutorial_py_canny.html
总结
在本教程中,您学习了如何在图像上应用 OpenCV 的 Canny 边缘检测和 Harris 角点检测算法。
具体来说,你学到了:
- 这些是基于像素的算法,它们将每个像素分类为边缘或非边缘,或角点或非角点。
- 如何使用 OpenCV 函数将这些算法应用于图像并解释结果。
如果您有任何问题,请在下方评论区提出。
暂无评论。