用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()
相关推荐
AI多Agent协作实战派3 小时前
【AI探索历程17】从“给自己用“到想“让别人用“
人工智能
吴佳浩4 小时前
Memory Provider 实战:Hermes、Mem0、Honcho、Hindsight 为什么都这样设计?
人工智能·agent·ai编程
吴佳浩4 小时前
企业级 Agent Memory 选型指南:如何构建可扩展的 Memory Service?
人工智能·agent·ai编程
北方的银狐-Zero5 小时前
ERP 管执行,数据管标准,OntoL本体 管思考:企业智能化升级的规划图
大数据·人工智能·本体论
浅安的邂逅5 小时前
260918-白帽把 OpenAI 论坛“打穿“了:攻防赛漏洞、账户被 Claude 入侵、模型偷偷掩盖不当行为
人工智能·大模型·ai编程·ai模型·行业动态
jinyishu_5 小时前
认识 AI Agent:概念、架构、设计模式与主流框架
人工智能
Hrain-AI6 小时前
AI 爬虫三档授权工程落地:搜索放行、训练拦截、Agent 分层(附脚本)
人工智能·elasticsearch·milvus
sunhy_csdn6 小时前
“词码”作为 Token 候选译名
人工智能
Hrain-AI6 小时前
多 Agent 并行不打架:worktree 隔离与反馈回流落地(附脚本)
网络·数据库·人工智能·架构