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

如何用Python与OpenCV将任意角度图像旋转至垂直0度?

用Python+OpenCV将任意倾斜图像纠正至垂直0度

完全可以实现你的需求,核心就是先检测图像的倾斜角度,再通过旋转操作抵消该角度。下面是具体的实现方案:

核心思路

  1. 图像预处理:将图像转为灰度并二值化,突出主体的轮廓/线条,为角度检测做准备
  2. 倾斜角度检测:通过霍夫变换检测直线角度,或通过轮廓的最小外接矩形提取旋转角度
  3. 图像旋转纠正:根据检测到的角度,对原图进行旋转,抵消倾斜并处理旋转后的黑边问题

代码实现

1. 导入依赖库

import cv2
import numpy as np

2. 图像预处理函数

def preprocess_image(image_path):
    # 读取图像
    img = cv2.imread(image_path)
    # 转为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 自适应二值化(适配不同光照条件)
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
    return img, thresh

3. 倾斜角度检测(两种可选方法)

方法一:霍夫变换检测直线角度

适合文本类图像,通过检测文本行的直线方向判断倾斜角度

def detect_angle_hough(thresh_img):
    # 检测图像中的直线
    lines = cv2.HoughLinesP(thresh_img, 1, np.pi/180, threshold=50, minLineLength=50, maxLineGap=10)
    angles = []
    for line in lines:
        x1, y1, x2, y2 = line[0]
        # 计算直线的倾斜角度(弧度转角度)
        angle = np.arctan2(y2 - y1, x2 - x1) * 180 / np.pi
        angles.append(angle)
    # 取角度中位数,避免异常值干扰
    median_angle = np.median(angles)
    # 调整角度至-45~45范围,对应垂直纠正的角度
    if median_angle < -45:
        median_angle += 90
    elif median_angle > 45:
        median_angle -= 90
    return median_angle
方法二:轮廓最小外接矩形检测角度

适合有明确主体的图像,通过主体轮廓的外接矩形获取旋转角度

def detect_angle_contour(thresh_img):
    # 寻找图像中的外部轮廓
    contours, _ = cv2.findContours(thresh_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # 筛选出面积最大的轮廓(假设为图像主体)
    largest_contour = max(contours, key=cv2.contourArea)
    # 获取轮廓的最小外接矩形
    rect = cv2.minAreaRect(largest_contour)
    angle = rect[2]
    # 调整角度至正确的纠正范围
    if angle < -45:
        angle += 90
    return angle

4. 图像旋转纠正函数

def rotate_image(image, angle):
    (h, w) = image.shape[:2]
    center = (w // 2, h // 2)
    # 生成旋转矩阵
    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), borderMode=cv2.BORDER_REPLICATE)
    return rotated

5. 主调用示例

if __name__ == "__main__":
    # 替换为你的图像路径
    img_path = "tilted_image.jpg"
    original_img, thresh_img = preprocess_image(img_path)
    
    # 选择一种角度检测方法
    # angle = detect_angle_hough(thresh_img)
    angle = detect_angle_contour(thresh_img)
    
    # 旋转图像(负角度抵消原有倾斜)
    rotated_img = rotate_image(original_img, -angle)
    
    # 保存结果并显示
    cv2.imwrite("vertical_image.jpg", rotated_img)
    cv2.imshow("Original", original_img)
    cv2.imshow("Vertical", rotated_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

注意事项

  • 预处理的二值化参数(如11和2)可能需要根据你的图像调整,确保主体轮廓清晰
  • 如果图像倾斜角度接近90度,两种方法都会自动调整为正确的纠正角度
  • 旋转时的borderMode参数可以替换为cv2.BORDER_CONSTANT,并用borderValue指定填充颜色

内容的提问来源于stack exchange,提问作者Jeremy Sapienza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:10:52