通过阈值分割提取图像中的目标物体前景,或者边缘提取目标物体的轮廓,在这些前景中可以寻找感兴趣的几何形状,如直线,圆,三角形,矩形等。
opencv中提供了拟合像素点的最小外包旋转矩形,最小外包直立矩形,最小外包圆,最小外包三角形和最小凸包,其对应函数使用如下:
opencv 中函数minAreaRect()计算坐标点集的最小外包面积矩形,返回矩形的中心坐标点,宽和高,以及旋转角度,一般再通过函数boxPoints()能活得矩形框的四个顶点坐标,两个函数的参数和返回值说明如下:
center, size, angle = cv2.minAreaRect(points) points: 坐标点array,数据类型为数据类型为int32或者float32 points = np.array([[154, 154],[253, 171], [154, 176],[248, 204]], np.int32) center: 旋转矩形的中心点 size: 矩形的宽,高; 结果可能为(h, w)或者(w, h) angle: 相对于x轴正方向的旋转角度,顺时针旋转为正数,逆时针旋转为负数,在(-90, 0)之间
vertices = cv2.boxPoints(box)
box: 为minAreaRect()的返回值
box = (center, size, angle), 注意为一个元组,最外面括号不能少
box = ((201.00001525878906, 179.00001525878906),
(33.37017059326172,101.1060562133789), -80.25636291503906)
vertices:返回矩形的四个顶点坐标
vertices=[[248.00002 204.00002],
[148.35243 186.88881],
[154.00002 154.00002],
[253.6476 171.11122]]
返回值中旋转角度值得注意一下:
1. 旋转角度θ是水平轴(x轴)逆时针旋转,与碰到的矩形的第一条边的夹角。并且这个边的边长是width,另一条边边长是height。也就是说,在这里,width与height不是按照长短来定义的。
2. 在opencv中,坐标系原点在左上角,相对于x轴,逆时针旋转角度为负,顺时针旋转角度为正。所以,θ∈(-90度,0]。
下面为minAreaRect() 的使用代码和示例:
#coding:utf-8 import cv2 import numpy as np def draw_rect(img_file, points): img = cv2.imread(img_file) center, size, angle = cv2.minAreaRect(points) #中心点坐标,尺寸,旋转角度 print(center, size, angle) vertices= cv2.boxPoints((center, size, angle)) print(vertices) for i in range(4): point1 = vertices[i, :] point2 = vertices[(i+1)%4, :] cv2.line(img, tuple(point1), tuple(point2), (0, 0, 255), 2) cv2.imshow("img", img) cv2.waitKey(0) cv2.destroyAllWindows() if __name__ == "__main__": img_file = r"D:\data\timg.jpg" points1 = np.array([[154, 154],[253, 171], [154, 176],[248, 204]], np.int32) # 数据类型为int32或者float32 draw_rect(img_file, points1) # points2 = np.array([[148, 171], [247, 153], [253, 186], [154, 204]], np.int32) # draw_rect(img_file, points2)