前言
Python OpenCV图像方框识别
Python Version: 3.11.9
引用库
numpy==1.26.4 opencv-python==4.9.0.80
安装命令:
pip install numpy==1.26.4 pip install opencv-python==4.9.0.80
实现代码
import cv2 as cv import numpy as np def find_and_draw_boxes(frame, max_depth=3, current_depth=1, offsetWidth = 0): if current_depth > max_depth: # 递归基准情形 return gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) # 将彩色图像转换为灰度图像 blurred = cv.GaussianBlur(gray, (5, 5), 0) # 对灰度图像进行高斯模糊 edged = cv.Canny(blurred, 75, 200) # 使用Canny边缘检测算法找到图像中的边缘 contours, _ = cv.findContours(edged.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) # 查找轮廓 if not contours: # 如果没有找到轮廓,直接返回 return for c in contours: area = cv.contourArea(c) # 计算轮廓的面积 if area < 500: # 面积过滤 continue # 获取最小的外接旋转矩形 rect = cv.minAreaRect(c) box = cv.boxPoints(rect) # 获取旋转矩形的四个顶点坐标 box = np.intp(box) # 将坐标值取整 aspect_ratio = float(rect[1][0])/float(rect[1][1]) # 计算长宽比 # 长宽比过滤 if aspect_ratio < 0.5 or aspect_ratio > 2: continue # 绘制旋转矩形 drawer = box.copy() if current_depth % 2 == 1: drawer[0][0] -= offsetWidth drawer[0][1] -= offsetWidth drawer[1][0] += offsetWidth drawer[1][1] -= offsetWidth drawer[2][0] += offsetWidth drawer[2][1] += offsetWidth drawer[3][0] -= offsetWidth drawer[3][1] += offsetWidth else: drawer[0][0] += offsetWidth drawer[0][1] += offsetWidth drawer[1][0] -= offsetWidth drawer[1][1] += offsetWidth drawer[2][0] -= offsetWidth drawer[2][1] -= offsetWidth drawer[3][0] += offsetWidth drawer[3][1] -= offsetWidth cv.drawContours(frame, [drawer], 0, (0, 0, 255), 2) # 在原始图像上绘制旋转矩形 # 计算并绘制中心的十字架 cx, cy = np.mean(box, axis=0) cv.line(frame, (int(cx - 10), int(cy)), (int(cx + 10), int(cy)), (0, 0, 255), 2) cv.line(frame, (int(cx), int(cy - 10)), (int(cx), int(cy + 10)), (0, 0, 255), 2) # 为下一层裁剪图像 if 0 < rect[1][1] < frame.shape[1] and 0 < rect[1][0] < frame.shape[0]: minX = min(box[:,0]) maxX = max(box[:,0]) minY = min(box[:,1]) maxY = max(box[:,1]) roi = frame[max(int(minY) + offsetWidth + 2,0):min(int(maxY) - offsetWidth + 2,frame.shape[0]), max(int(minX) + offsetWidth + 2,0):min(int(maxX) - offsetWidth + 2,frame.shape[1])] find_and_draw_boxes(roi, max_depth, current_depth + 1, offsetWidth) # 递归调用函数处理下一层图像 break # 打开摄像头 cap = cv.VideoCapture(0) while True: ret, frame = cap.read() # 读取摄像头捕获的每一帧图像 if not ret: break find_and_draw_boxes(frame, max_depth=4, offsetWidth=5) # 调用函数处理图像 cv.imshow('Frame with Rotated Boxes', frame) # 显示处理后的图像 if cv.waitKey(1) & 0xFF == ord('q'): # 如果按下'q'键,退出循环 break cap.release() # 释放摄像头资源 cv.destroyAllWindows() # 关闭所有窗口
温馨提示:注释由人工智能提供
最新评论