目录
一、概述
1.1意义
1.2应用
二、代码实现
三、实现效果
3.1原始图像
3.2处理后图像
3.3数据输出
一、概述
最小外包围矩形(Minimum Bounding Rectangle, MBR)在计算机视觉和图像处理中的意义和应用非常广泛。它是指能够完全包围目标的最小矩形,其主要特性是矩形的面积最小,并且边与目标最紧密。
1.1意义
1.描述性紧凑:最小外包围矩形提供了一种紧凑的方式来描述目标的位置和范围。与边界框不同,最小外包围矩形会根据目标的形状和方向调整自身的角度,从而更贴近目标。
2.旋转不变性:最小外包围矩形能够适应目标的旋转,提供了一种与目标方向无关的边界描述。
3.计算效率:计算最小外包围矩形相对高效,且可以为后续的图像处理步骤提供简化数据。
1.2应用
1.目标检测与跟踪:
检测:通过找到目标的最小外包围矩形,可以更精确地定位目标的位置和方向。
跟踪:在视频跟踪中,可以使用最小外包围矩形来跟踪目标的变化,包括位置和旋转。
2.形状分析与特征提取:
方向与角度:通过最小外包围矩形,可以确定目标的主方向和旋转角度。
形状描述:最小外包围矩形的长宽比可以用于形状分析,帮助区分不同的目标类型。
3.图像裁剪与矫正:裁剪:使用最小外包围矩形可以精确地裁剪目标,去除不必要的背景部分。
矫正:在文档扫描中,可以使用最小外包围矩形来检测并矫正图像的倾斜角度。
4.对象检测前处理:在对象检测的前处理中,可以使用最小外包围矩形来规范化目标的位置和方向,从而提高检测算法的准确性。
5.形状拟合:在三维重建和点云处理中,最小外包围矩形可以用于拟合形状,简化复杂形状的描述。
二、代码实现
import cv2
import numpy as np
from scipy.spatial import distance# 加载图片
image = cv2.imread('jiaodian.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 二值化处理
_, binary = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY_INV)# 查找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]# 计算最小外接矩形
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box) # 转换为整数# 计算四条边的长度
edges = [np.linalg.norm(box[i] - box[(i + 1) % 4]) for i in range(4)]
longest_edge = max(edges)
shortest_edge = min(edges)# 计算角点之间的距离
dist_matrix = distance.cdist(box, box, 'euclidean')
np.fill_diagonal(dist_matrix, np.inf) # 防止自己到自己的距离被选中# 找到距离最短的两对角点
min_dist_idx_1 = np.unravel_index(np.argmin(dist_matrix), dist_matrix.shape)
nearest_points_1 = box[list(min_dist_idx_1)]
dist_matrix[min_dist_idx_1] = np.inf # 将最短距离设为无穷大,以找到第二短的距离min_dist_idx_2 = np.unravel_index(np.argmin(dist_matrix), dist_matrix.shape)
nearest_points_2 = box[list(min_dist_idx_2)]# 绘制结果
for i, point in enumerate(box):cv2.circle(image, tuple(point), 8, (0, 0, 255), -1)cv2.putText(image, chr(65 + i), tuple(point), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)# 绘制矩形框
cv2.drawContours(image, [box], 0, (0, 255, 0), 2)# 绘制最近的两对点之间的线
cv2.line(image, tuple(nearest_points_1[0]), tuple(nearest_points_1[1]), (0, 0, 255), 3)
cv2.line(image, tuple(nearest_points_2[0]), tuple(nearest_points_2[1]), (0, 0, 255), 3)# 显示结果
cv2.imshow("Min Area Rect", image)
cv2.waitKey(0)
cv2.destroyAllWindows()# 打印结果
print(f"The four corner points of the minimum area bounding box are: {box}")
print(f"Longest edge length: {longest_edge}")
print(f"Shortest edge length: {shortest_edge}")
print(f"The nearest two points are: {nearest_points_1[0]} and {nearest_points_1[1]}")
print(f"Their distance is: {dist_matrix[min_dist_idx_1]}")
print(f"The second nearest two points are: {nearest_points_2[0]} and {nearest_points_2[1]}")
print(f"Their distance is: {dist_matrix[min_dist_idx_2]}")
代码解释:
1.加载图片并转换为灰度图:使用 cv2.imread 加载图片,使用 cv2.cvtColor 转换为灰度图。
2.二值化处理:使用 cv2.threshold 进行二值化处理,将黑色矩形变为白色区域,背景变为黑色。
3.查找轮廓:使用 cv2.findContours 查找轮廓,并选择第一个轮廓。
4.计算最小外接矩形:使用 cv2.minAreaRect 计算最小外接矩形,并使用 cv2.boxPoints 获取矩形的四个角点。
5.计算四条边的长度:通过计算角点之间的欧几里得距离,找到矩形的四条边的长度。
6.找到最长边和最短边的长度:通过比较边长找到最长边和最短边的长度。
7.计算角点之间的距离:使用 scipy.spatial.distance.cdist 函数计算角点之间的欧几里得距离,并用 np.fill_diagonal 将自己到自己的距离设为无穷大,防止被选中。
8.找到距离最短的两对角点:通过找出距离矩阵中最小的两个值及其索引,确定最近的两对角点。
9.绘制结果:在图像上绘制最小外接矩形、四个角点(用字母标记)和最近的两对角点之间的线,并显示结果。
三、实现效果
3.1原始图像
3.2处理后图像
3.3数据输出
The four corner points of the minimum area bounding box are: [[166 120][705 120][705 320][166 320]]
Longest edge length: 539.0
Shortest edge length: 200.0
The nearest two points are: [166 120] and [166 320]
Their distance is: inf
The second nearest two points are: [705 120] and [705 320]
Their distance is: 200.0