图像分析与特征提取
本章介绍OpenCV中的图像分析和特征提取技术,这些是计算机视觉应用中的核心能力。
图像直方图分析
直方图是图像中像素值分布的统计表示,是理解图像特性的有力工具。
灰度直方图
# 计算灰度直方图
hist = cv2.calcHist([gray_img], [0], None, [256], [0, 256])
颜色直方图
# 计算RGB三通道直方图
color = ('b', 'g', 'r')
for i, col in enumerate(color):
histr = cv2.calcHist([img], [i], None, [256], [0, 256])
# 绘制每个通道的直方图
掩码直方图
# 创建ROI区域的掩码
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
# 使用掩码计算直方图
masked_hist = cv2.calcHist([img], [0], mask, [256], [0, 256])
直方图均衡化
直方图均衡化是一种常用的图像增强技术,可以提高图像的对比度:
# 应用直方图均衡化
equalized = cv2.equalizeHist(gray_img)
# 自适应直方图均衡化(CLAHE) - 减少过度增强噪声
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
clahe_img = clahe.apply(gray_img)
直方图比较
# 计算两个直方图之间的相似度
similarity = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL)
比较方法 | 描述 | 最佳匹配值 |
---|---|---|
HISTCMP_CORREL | 相关性 | 接近1 |
HISTCMP_CHISQR | 卡方 | 接近0 |
HISTCMP_INTERSECT | 交集 | 越大越好 |
HISTCMP_BHATTACHARYYA | 巴氏距离 | 接近0 |
图像轮廓分析
基本轮廓检测
# 获取图像轮廓
contours, hierarchy = cv2.findContours(
binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
# 绘制轮廓
contour_img = img.copy()
cv2.drawContours(contour_img, contours, -1, (0, 255, 0), 2)
轮廓层次结构
轮廓层次结构表示轮廓之间的包含关系:
检索模式 | 描述 | 应用场景 |
---|---|---|
RETR_EXTERNAL | 只检索最外层轮廓 | 物体计数、简单形状检测 |
RETR_LIST | 检索所有轮廓,无层次关系 | 全部轮廓分析、简单场景 |
RETR_CCOMP | 检索所有轮廓,两层层次结构 | 物体内部和外部轮廓分析 |
RETR_TREE | 检索所有轮廓,完整层次结构 | 复杂场景、嵌套对象分析 |
轮廓属性分析
# 计算轮廓的面积
area = cv2.contourArea(contour)
# 计算轮廓的周长
perimeter = cv2.arcLength(contour, True) # True表示闭合轮廓
# 获取轮廓的边界矩形
x, y, w, h = cv2.boundingRect(contour)
# 获取轮廓的最小外接矩形
rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rect)
box = np.int0(box)
边界矩形
最小外接矩形
最小外接圆
形状描述符
# 计算轮廓的Hu矩
moments = cv2.moments(contour)
hu_moments = cv2.HuMoments(moments)
# 计算轮廓的质心
cx = int(moments['m10'] / moments['m00'])
cy = int(moments['m01'] / moments['m00'])
# 计算轮廓的形状特征
solidity = area / cv2.contourArea(cv2.convexHull(contour))
aspect_ratio = float(w) / h
extent = area / (w * h)
形状描述符应用
- Hu矩: 旋转、缩放和平移不变性,适合形状匹配
- 质心: 定位物体中心,追踪物体运动
- 凸度: 检测物体的凹陷程度,识别特定形状
- 纵横比: 区分长形和方形物体
凸包检测
# 计算轮廓的凸包
hull = cv2.convexHull(contour)
# 绘制凸包
hull_img = img.copy()
cv2.drawContours(hull_img, [hull], 0, (0, 0, 255), 2)
原始轮廓
→
凸包
凸缺陷
凸缺陷是物体轮廓与其凸包之间的差异,常用于手势识别等场景。
# 查找凸缺陷
defects = cv2.convexityDefects(contour, cv2.convexHull(contour, returnPoints=False))
# 处理凸缺陷点
for i in range(defects.shape[0]):
s, e, f, d = defects[i, 0]
start = tuple(contour[s][0])
end = tuple(contour[e][0])
far = tuple(contour[f][0])
# 绘制凸缺陷点和线
cv2.line(img, start, end, [0, 255, 0], 2)
cv2.circle(img, far, 5, [0, 0, 255], -1)
特征点检测与匹配
Harris角点检测
角点是图像中梯度在多个方向变化显著的点。
# Harris角点检测
corners = cv2.cornerHarris(gray_img.astype(np.float32), 2, 3, 0.04)
# 标记角点
corner_img = img.copy()
corner_img[corners > 0.01 * corners.max()] = [0, 0, 255]
Harris角点
SIFT和SURF特征
SIFT(尺度不变特征变换)和SURF(加速稳健特征)是强大的特征检测算法,可用于对象识别和图像匹配。
注意
SIFT和SURF是专利算法,需要通过安装 opencv-contrib-python
才能使用。
# 创建SIFT检测器
sift = cv2.SIFT_create()
# 检测关键点和计算描述符
keypoints, descriptors = sift.detectAndCompute(gray_img, None)
# 绘制关键点
sift_img = cv2.drawKeypoints(img, keypoints, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
ORB特征
ORB (Oriented FAST and Rotated BRIEF) 是一种开源替代方案,速度快且无专利限制。
# 创建ORB检测器
orb = cv2.ORB_create()
# 检测关键点和计算描述符
keypoints, descriptors = orb.detectAndCompute(gray_img, None)
# 绘制关键点
orb_img = cv2.drawKeypoints(img, keypoints, None, color=(0, 255, 0))
特征匹配
# 创建BF匹配器
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# 匹配描述符
matches = bf.match(descriptors1, descriptors2)
# 按距离排序
matches = sorted(matches, key=lambda x: x.distance)
# 绘制前N个匹配
match_img = cv2.drawMatches(img1, keypoints1, img2, keypoints2, matches[:30], None)
特征分类比较
特征类型 | 优势 | 劣势 | 适用场景 |
---|---|---|---|
Harris角点 | 简单快速、准确定位 | 不具尺度不变性 | 简单场景、实时应用 |
SIFT | 尺度、旋转不变性强 | 计算较慢、专利限制 | 复杂场景匹配、全景拼接 |
SURF | 比SIFT更快、不变性良好 | 专利限制、略微降低精度 | 高速场景、目标跟踪 |
ORB | 非常快速、无专利限制 | 不变性弱于SIFT/SURF | 实时应用、低计算资源环境 |
实际应用案例
模板匹配
# 模板匹配
result = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
# 获取最佳匹配位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
# 根据匹配方法确定匹配位置
top_left = max_loc # 对于TM_CCOEFF_NORMED方法
bottom_right = (top_left[0] + w, top_left[1] + h)
# 绘制矩形框标记匹配区域
cv2.rectangle(img, top_left, bottom_right, 255, 2)
全景图像拼接
# 1. 检测特征点和描述符
keypoints1, descriptors1 = sift.detectAndCompute(gray1, None)
keypoints2, descriptors2 = sift.detectAndCompute(gray2, None)
# 2. 特征匹配
matches = bf.knnMatch(descriptors1, descriptors2, k=2)
# 3. 应用比率测试筛选好的匹配
good_matches = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good_matches.append(m)
# 4. 找到变换矩阵
src_pts = np.float32([keypoints1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
dst_pts = np.float32([keypoints2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
# 5. 应用变换
result = cv2.warpPerspective(img1, M, (img1.shape[1] + img2.shape[1], img1.shape[0]))
result[0:img2.shape[0], 0:img2.shape[1]] = img2
总结与拓展方向
技术 | 核心应用 | 进阶方向 |
---|---|---|
直方图分析 | 图像分类、对比度增强 | 多维直方图、深度学习与直方图融合 |
轮廓分析 | 形状识别、目标检测 | 多尺度轮廓分析、实时轮廓跟踪 |
特征点检测 | 图像匹配、物体识别 | 深度学习特征点、语义特征点 |
特征匹配 | 图像拼接、目标检测 | 鲁棒特征匹配、特征融合策略 |
掌握这些图像分析和特征提取技术后,您可以开发更智能的计算机视觉应用,如物体识别、图像搜索、增强现实等。结合深度学习,更可以实现更复杂的视觉理解任务。