如何对0~360度任意朝向的图像进行拉直校正 现有旋转算法效果不佳
任意朝向图像拉直校正方案
现有代码缺陷
cv2.minAreaRect()返回的角度取值范围仅为[-90, 0),原有角度转换逻辑仅支持±45°以内的小角度倾斜校正,无法适配90°、180°、270°等大角度旋转场景- 旋转操作直接使用原始图像宽高作为输出尺寸,大角度旋转后会出现内容裁切
- 未做文本朝向校验,校正后可能出现文字倒置的问题
- 仅使用阈值化后的像素坐标计算最小外接矩形,容易受噪点影响导致角度计算偏差
你提供的3张测试示例图像如下:


调整后的完整代码
# 导入所需依赖包 import matplotlib.pyplot as plt import numpy as np import cv2 def plt_imshow(title, image): # opencv默认BGR格式,转RGB适配matplotlib显示 image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) plt.imshow(image) plt.title(title) plt.grid(False) plt.show() def get_rotate_correction(image): # 灰度处理+反色+阈值分割 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.bitwise_not(gray) thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] # 形态学操作去除噪点,优化轮廓检测效果 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3)) thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2) # 查找最大轮廓,避免零散噪点干扰角度计算 contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) contours = sorted(contours, key=cv2.contourArea, reverse=True) max_contour = contours[0] # 计算最小外接矩形角度 angle = cv2.minAreaRect(max_contour)[-1] # 全角度转换逻辑 if angle < -45: angle = 90 + angle # 文本倒置判断:通过行像素投影判断朝向是否正确 (h, w) = image.shape[:2] center = (w // 2, h // 2) M_test = cv2.getRotationMatrix2D(center, angle, 1.0) rotated_test = cv2.warpAffine(thresh, M_test, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE) row_sum = np.sum(rotated_test, axis=1) top_sum = np.sum(row_sum[:h//2]) bottom_sum = np.sum(row_sum[h//2:]) # 下半部分有效像素和远低于上半部分时,判定为文本倒置,补充180度旋转 if bottom_sum < top_sum * 0.7: angle += 180 # 计算旋转后无裁切的新图像尺寸 M = cv2.getRotationMatrix2D(center, angle, 1.0) cos = np.abs(M[0, 0]) sin = np.abs(M[0, 1]) new_w = int((h * sin) + (w * cos)) new_h = int((h * cos) + (w * sin)) # 调整旋转矩阵偏移量,避免内容错位 M[0, 2] += (new_w / 2) - center[0] M[1, 2] += (new_h / 2) - center[1] # 执行最终旋转 rotated = cv2.warpAffine(image, M, (new_w, new_h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE) return rotated, angle if __name__ == "__main__": args = { "image": "C:/Users/tskta/Desktop/Images rotation/all rotations/75.png" } # 从磁盘加载图像 image = cv2.imread(args["image"]) rotated, angle = get_rotate_correction(image) # 在图像上标注校正角度,方便验证效果 cv2.putText(rotated, "Angle: {:.2f} degrees".format(angle), (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) # 展示输出图像 print("[INFO] angle: {:.3f}".format(angle)) plt_imshow("Input", image) plt_imshow("Rotated", rotated) cv2.imwrite("Downloads/rotated.png", rotated)
效果说明
上述代码可支持0~360°任意朝向的文本类图像校正,不会出现内容裁切、文字倒置的问题,适配你提供的3种不同旋转角度的测试场景。如果需要更高的角度识别精度,可引入Tesseract OCR的方向检测模块替换现有投影判断逻辑。
内容的提问来源于stack exchange,提问作者Tsk208
相关产品推荐
相关产品推荐

