You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对0~360度任意朝向的图像进行拉直校正 现有旋转算法效果不佳

任意朝向图像拉直校正方案

现有代码缺陷

  • cv2.minAreaRect()返回的角度取值范围仅为[-90, 0),原有角度转换逻辑仅支持±45°以内的小角度倾斜校正,无法适配90°、180°、270°等大角度旋转场景
  • 旋转操作直接使用原始图像宽高作为输出尺寸,大角度旋转后会出现内容裁切
  • 未做文本朝向校验,校正后可能出现文字倒置的问题
  • 仅使用阈值化后的像素坐标计算最小外接矩形,容易受噪点影响导致角度计算偏差

你提供的3张测试示例图像如下:
img_1_75
img_2_90
img_3_45

调整后的完整代码

# 导入所需依赖包
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 19:54:05