如何检测图像中错位矩形并将其旋转至正确方向
图像块错位检测与旋转修正方案
问题背景
现有crop_image函数用于从图像中裁剪目标块,但在处理相机拍摄的非理想输入图时,会出现裁剪块方向错位的问题(比如原本竖置的块被横置裁剪),需要实现错位检测与自动旋转修正。
原函数代码:
def crop_image(self,img): cnts,gray_img = self.pre_processing_img(img) ans_blocks = [] x_old, y_old, w_old, h_old = 0, 0, 0, 0 if len(cnts) > 0: cnts = sorted(cnts, key=self.get_x_ver1) for i, c in enumerate(cnts): x_curr, y_curr, w_curr, h_curr = cv2.boundingRect(c) if w_curr * h_curr > 100000 and w_curr < h_curr: check_xy_min = x_curr * y_curr - x_old * y_old check_xy_max = (x_curr + w_curr) * (y_curr + h_curr) - (x_old + w_old) * (y_old + h_old) if len(ans_blocks) == 0: cv2.imshow("test", gray_img[y_curr:y_curr + h_curr, x_curr:x_curr + w_curr]) cv2.waitKey(0) cv2.destroyAllWindows() ans_blocks.append( (gray_img[y_curr:y_curr + h_curr, x_curr:x_curr + w_curr],[x_curr,y_curr,w_curr,h_curr])) x_old,y_old,w_old,h_old = x_curr,y_curr,w_curr,h_curr elif check_xy_min > 20000 and check_xy_max > 20000: ans_blocks.append( (gray_img[y_curr:y_curr + h_curr, x_curr:x_curr + w_curr],[x_curr,y_curr,w_curr,h_curr])) x_old,y_old,w_old,h_old = x_curr,y_curr,w_curr,h_curr sorted_ans_blocks = sorted(ans_blocks, key=self.get_x) return sorted_ans_blocks
错位检测方法
1. 文本方向检测(最适用于文档类图像)
利用OCR工具检测图像内文本的旋转角度,直接判断图像块的正确方向。以Tesseract为例:
import pytesseract from PIL import Image def detect_text_orientation(img): pil_img = Image.fromarray(img) osd_info = pytesseract.image_to_osd(pil_img) for line in osd_info.split('\n'): if line.startswith('Orientation in degrees:'): return int(line.split(':')[-1].strip()) return 0
该方法能直接返回0/90/180/270度的旋转角度,准确率高。
2. 边缘统计辅助检测
如果无法使用OCR,可通过边缘方向统计判断:
- 对裁剪块做Canny边缘检测
- 统计水平边缘与垂直边缘的数量占比
- 若垂直边缘占比远高于水平,说明图像块需顺时针旋转90度;反之则逆时针旋转
旋转修正实现
基于检测到的角度,用OpenCV完成旋转:
import cv2 def rotate_image(img, angle): if angle == 90: return cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE) elif angle == 180: return cv2.rotate(img, cv2.ROTATE_180) elif angle == 270: return cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE) return img
集成到现有函数
在原函数的图像块添加逻辑中,插入检测与修正步骤:
# 替换原ans_blocks.append的逻辑 crop_block = gray_img[y_curr:y_curr + h_curr, x_curr:x_curr + w_curr] # 检测方向并修正 rot_angle = detect_text_orientation(crop_block) corrected_block = rotate_image(crop_block, rot_angle) # 修正bounding rect的宽高(旋转90/270度时宽高互换) corrected_rect = [x_curr, y_curr, w_curr, h_curr] if rot_angle in [90, 270]: corrected_rect[2], corrected_rect[3] = h_curr, w_curr ans_blocks.append( (corrected_block, corrected_rect) )
额外优化建议
针对相机拍摄的倾斜输入图,可在预处理阶段先做透视矫正:
- 检测图像中最大的四边形轮廓(文档边缘)
- 通过透视变换将文档矫正为正矩形
- 再执行裁剪操作,从根源减少错位概率
内容的提问来源于stack exchange,提问作者YSKM
相关产品推荐
相关产品推荐

