在计算机视觉和图像处理中,我们经常需要计算直线与外接矩形边的交点。这在进行边缘检测、图像分割、目标跟踪等任务时非常有用。本文将介绍如何使用OpenCV和NumPy计算直线与外接矩形边的交点,并展示如何在实际图像中绘制直线。
import cv2
import numpy as np
# 读取二值图像
img = cv2.imread('./111.png', cv2.IMREAD_GRAYSCALE)
使用OpenCV的findContours函数寻找图像中的轮廓。这里我们选择RETR_EXTERNAL表示只检测最外层轮廓,CHAIN_APPROX_SIMPLE表示压缩水平、垂直和对角线方向的元素,只保留它们的终点坐标。
# 寻找轮廓
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
找到所有轮廓后,我们选择面积最大的轮廓,即目标物体所在的区域。
# 获取最大轮廓(白色区域)
max_contour = max(contours, key=cv2.contourArea)
使用minAreaRect函数计算最小外接矩形的信息,包括中心点、尺寸和旋转角度。
# 计算最小外接矩形
rect = cv2.minAreaRect(max_contour)
box = cv2.boxPoints(rect)
box = np.intp(box)
使用minAreaRect函数计算最小外接矩形的信息,包括中心点、尺寸和旋转角度。
# 在原图上绘制最小外接矩形
result_img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
cv2.drawContours(result_img, [box], 0, (0, 255, 0), 2)
完整demo如下
import cv2
import numpy as np
# 读取二值图像
img = cv2.imread('./111.png', cv2.IMREAD_GRAYSCALE)
# 寻找轮廓
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 获取最大轮廓(白色区域)
max_contour = max(contours, key=cv2.contourArea)
# 计算最小外接矩形
rect = cv2.minAreaRect(max_contour)
box = cv2.boxPoints(rect)
box = np.intp(box)
# 在原图上绘制最小外接矩形
result_img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
cv2.drawContours(result_img, [box], 0, (0, 255, 0), 2)
cv2.imshow('result', result_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 计算外接矩形的 y 方向上的长度
center, size, angle = rect
width, height = size
# 计算直线与外接框的上边和下边的交点
x_pos = int(center[0])
y_pos_top = int(center[1] - height / 2)
y_pos_bottom = int(center[1] + height / 2)
# 计算直线的两个端点与外接矩形的边相交
line_top = ((x_pos, y_pos_top), (x_pos, y_pos_top + height))
line_bottom = ((x_pos, y_pos_bottom), (x_pos, y_pos_bottom - height))
# 计算直线与外接矩形边的交点
intersection_top = (x_pos, max(y_pos_top, min(y_pos_bottom, box[2][1])))
intersection_bottom = (x_pos, max(y_pos_top, min(y_pos_bottom, box[1][1])))
# 如果直线直接与外接矩形相交,交点就是直线的起点或者结束点
start_point = intersection_top if intersection_top in line_top else line_top[0]
end_point = intersection_bottom if intersection_bottom in line_bottom else line_bottom[0]
# 绘制直线
cv2.line(result_img, start_point, end_point, (0, 0, 255), 2)
# 显示图像
cv2.imshow('result', result_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
本文详细介绍了使用OpenCV进行图像处理的一系列步骤,包括读取图像、寻找轮廓、计算最小外接矩形和绘制相交直线。