用opencv校正图片的方向

校正的过程可以分为以下几步:

1、转灰度图。

2、降噪。

3、Canny边缘检测。

4、膨胀。

5、轮廓检索。

6、从各个轮廓中选取合适的旋转角度并校正图像。

python 复制代码
import cv2
import numpy as np


def resize_image(image, scale_factor):
    """调整图像大小"""
    return cv2.resize(
        image, None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_AREA
    )


def main():
    # 读取图像
    src = cv2.imread("images/c3.jpg")
    if src is None:
        print("无法读取图像,请检查路径是否正确!")
        return

    # 调整图像大小以便展示
    scale_factor = 0.5  # 缩放比例
    src_resized = resize_image(src, scale_factor)
    cv2.imshow("src", src_resized)

    # 转灰度图
    gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    gray_resized = resize_image(gray, scale_factor)
    cv2.imshow("gray", gray_resized)

    # 高斯模糊降噪
    blur = cv2.GaussianBlur(gray, (5, 5), 1.0)
    blur_resized = resize_image(blur, scale_factor)
    cv2.imshow("gaussianBlur", blur_resized)

    # Canny边缘检测
    canny = cv2.Canny(blur, 20, 100)
    canny_resized = resize_image(canny, scale_factor)
    cv2.imshow("canny", canny_resized)

    # 膨胀两次,让文字连到一块
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (4, 2))
    expand = cv2.dilate(canny, kernel, iterations=2)
    expand_resized = resize_image(expand, scale_factor)
    cv2.imshow("dialate", expand_resized)

    # 检索轮廓
    contours, _ = cv2.findContours(expand, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

    # 对各个轮廓的旋转角度进行排序
    vecAngles = []
    for contour in contours:
        rr = cv2.minAreaRect(contour)
        vecAngles.append(rr[2])  # RotatedRect.angle

    vecAngles.sort()

    # 以中间值为基准,取相差20%以内的角度的平均值作为结果
    midIndex = int(len(vecAngles) / 2) - 1
    midAngle = vecAngles[midIndex]
    maxAngleThreshold = midAngle + 15 if midAngle > 0 else midAngle - 15
    minAngleThreshold = midAngle - 15 if midAngle > 0 else midAngle + 15

    print("maxAngleThreshold:", maxAngleThreshold)
    print("minAngleThreshold:", minAngleThreshold)

    angleSum = 0
    angleCounter = 0
    for angle in vecAngles:
        print(angle)
        if minAngleThreshold < angle < maxAngleThreshold:
            angleSum += angle
            angleCounter += 1

    averageAngle = angleSum / angleCounter if angleCounter > 0 else 0
    print("averageAngle:", averageAngle)
    print("midAngle:", midAngle)

    # 旋转图像
    (h, w) = src.shape[:2]
    center = (w // 2, h // 2)
    rotateM = cv2.getRotationMatrix2D(center, averageAngle, 1.0)
    result = cv2.warpAffine(
        src,
        rotateM,
        (w, h),
        flags=cv2.INTER_LINEAR,
        borderMode=cv2.BORDER_CONSTANT,
        borderValue=(255, 255, 255),
    )
    result_resized = resize_image(result, scale_factor)
    cv2.imshow("result", result_resized)

    # 保存最终结果
    output_path = "result.jpg"
    cv2.imwrite(output_path, result)
    print(f"最终结果已保存到:{output_path}")

    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == "__main__":
    main()
相关推荐
镜象科技3 小时前
AI情感大模型应用场景全解:从校园到医院再到企业的落地地图
人工智能
Joshua-a4 小时前
工程数学-理解卷积的含义_线性时不变系统的冲激响应与卷积
人工智能·深度学习
song5014 小时前
React Native for OpenHarmony 实战:三方库 react-native-css-transformer 的鸿蒙化适配指南
css·人工智能·深度学习·react native·transformer
老金带你玩AI8 小时前
ChatGPT dots,到底能替你操多少心?
人工智能
AliCloudROS9 小时前
计算巢 X DeepSeek Harness — 云端智能体工作台
人工智能·阿里云
深蓝AI9 小时前
GitHub的Push一年涨4.9倍:AI Agent为什么逼它重做Git存储?
人工智能·github
stereohomology9 小时前
大模型的观点谨:StoryTold 「Crafting Apps」四件套 · 深度总览
人工智能·llm
运维行者_10 小时前
网络性能监控怎么做?从自动发现到根因分析的4个环节
运维·服务器·网络·人工智能·支持向量机
Su米苏10 小时前
Spring AI 中MCP 与普通 @Tool的区别
java·人工智能·spring
美狐美颜sdk10 小时前
直播APP源码可以直接接入视频美颜sdk吗?技术方案详解
android·人工智能·音视频·美颜sdk·直播美颜sdk