如何修复OpenCV提取旋转形状时的轮廓冗余与主轴对齐问题?
解决OpenCV提取校正旋转形状的两个问题
问题1:提取区域包含轮廓外多余内容
用**轮廓掩码(Mask)**实现精准裁剪,仅保留轮廓内的像素:
- 创建与原图尺寸一致的全黑掩码图像
- 调用
cv2.drawContours()将目标轮廓填充到掩码中(厚度设为cv2.FILLED) - 对原图和掩码执行
cv2.bitwise_and()操作,得到仅包含轮廓区域的图像
示例代码:
import cv2 import numpy as np # 假设已获取目标轮廓cnt img = cv2.imread("target_image.png") mask = np.zeros_like(img) cv2.drawContours(mask, [cnt], 0, (255,255,255), cv2.FILLED) cropped_img = cv2.bitwise_and(img, mask)
问题2:最小外接框未对齐主轴、图形无法直立且有黑边
改用**最小外接旋转矩形(minAreaRect)**获取轮廓主轴方向,通过仿射变换完成直立校正,同时裁剪黑边:
- 用
cv2.minAreaRect()获取轮廓的旋转矩形,返回中心坐标、宽高、旋转角度 - 根据矩形宽高调整角度,避免90度偏差导致的反向旋转
- 计算旋转矩阵,调用
cv2.warpAffine()执行旋转 - 重新提取旋转后图像的轮廓,用外接矩形裁剪掉黑边区域
示例代码:
# 获取最小外接旋转矩形 rect = cv2.minAreaRect(cnt) box = cv2.boxPoints(rect) box = np.int0(box) # 调整角度确保图形直立 width, height = rect[1] angle = rect[2] if width < height: angle += 90 # 生成旋转矩阵并执行旋转 center = rect[0] rot_mat = cv2.getRotationMatrix2D(center, angle, 1.0) rotated_img = cv2.warpAffine(cropped_img, rot_mat, (img.shape[1], img.shape[0]), flags=cv2.INTER_CUBIC) # 裁剪旋转后的有效区域(去除黑边) rotated_gray = cv2.cvtColor(rotated_img, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(rotated_gray, 1, 255, cv2.THRESH_BINARY) rotated_cnts, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) x, y, w, h = cv2.boundingRect(rotated_cnts[0]) final_img = rotated_img[y:y+h, x:x+w]
额外提示:提取轮廓时建议用cv2.RETR_EXTERNAL仅保留最外层轮廓,避免掩码填充时包含内部空洞或干扰轮廓。
内容的提问来源于stack exchange,提问作者Ξένη Γήινος
相关产品推荐
相关产品推荐

