通过阈值分割提取图像中的目标物体前景,或者边缘提取目标物体的轮廓,在这些前景中可以寻找感兴趣的几何形状,如直线,圆,三角形,矩形等。

1. 点集的最小外包

  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]。

(七)OpenCV-Python学习—几何形状拟合

  下面为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)
minAreaRect()

相关文章: