函数使用方法
min_rect = cv2.minAreaRect(cnt)
# 输入参数cnt是通过findContours识别出来的轮廓信息
# 输出min_rect是一个元组,其中的结构是最小外接矩形的(中心(x,y),(边1长度,边2长度),旋转角度)
简单测试一下对几个角度的矩形和平行四边形的识别效果
图片可能较小,建议放大观看
可以看到,输出的旋转角度和矩形边2的选择有关,具体函数是按照什么规则来确定边1和边2,我还不清楚,但是根据上面的实验结论,大致可以推测出以下规律:
规定水平矩阵为上图第一个矩形形状,即长边平行于x轴,短边垂直于x轴,
按住水平矩形的左上角,逆时针旋转矩形不超过90度 形成的矩形,长边作为边2;
按住水平矩形的左上角,顺时针旋转矩形小于90度 形成的矩形,短边作为边2。
如有错误,欢迎在评论区指正!
以下是代码部分
测试图片位置:https://github.com/lly327/opencv/tree/main/datasets/rect_parallelogram
import cv2
from matplotlib import pyplot as plt
import os
import numpy as np
def plt_show0(img):
# cv2与plt的图像通道不同:cv2为[b,g,r];plt为[r, g, b]
b, g, r = cv2.split(img)
img = cv2.merge([r, g, b])
plt.imshow(img)
plt.show()
def test_min_area_rect():
test_dir = '/home/lily/EfficientNet_pytorch/platenumber/test2' # 测试图片存放目录
imgs_name = os.listdir(test_dir)
imgs_name = sorted(imgs_name)
for img_name in imgs_name:
print()
img_path = os.path.join(test_dir, img_name)
ori_img = cv2.imread(img_path) # rgb图,用于展示矩形轮廓线
# 灰度方式读取
img = cv2.imread(img_path, 0)
# 二值化,必须经过二值化后才能进行findContours
ret, img = cv2.threshold(img, 120, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 找到最小外接矩形
for i in range(len(contours)):
cnt = contours[i]
min_rect = cv2.minAreaRect(cnt) # 得到最小外接矩形的(中心(x,y), (边1,边2), 旋转角度)
points = cv2.boxPoints(min_rect) # 矩形的四个顶点坐标
points = np.int0(points)
cv2.drawContours(ori_img, [points], 0, (0, 255, 0), 5) # 画绿线
plt_show0(ori_img)
print(f"img_name:{img_name},side1:{int(min_rect[1][0])},side2:{int(min_rect[1][1])},rotate_angle:{round(min_rect[2],2)}")
if __name__ == '__main__':
test_min_area_rect()
输出结果
img_name:7水平矩形填充.jpg, side1:198, side2:483, rotate_angle:90.0
img_name:8水平平行四边形.jpg, side1:198, side2:680, rotate_angle:90.0
img_name:9正45矩形.jpg, side1:197, side2:483, rotate_angle:45.0
img_name:10正45平行四边形.jpg, side1:198, side2:681, rotate_angle:44.91
img_name:11负45矩形.jpg, side1:483, side2:197, rotate_angle:45.0
img_name:12负45平行四边形.jpg, side1:681, side2:198, rotate_angle:45.1