用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()
相关推荐
Raink老师14 小时前
【AI面试临阵磨枪-79】实时数据 RAG:订单、商家、物流、天气、动态库存
人工智能·面试·职场和发展
脑极体14 小时前
点亮星河AI+鸿蒙,一座艺术场馆的日神觉醒
人工智能·华为·harmonyos
Cosolar14 小时前
Chroma向量库面试学习指南
数据库·人工智能·面试·职场和发展·数据库架构
BUG指挥官14 小时前
Claude Code的自动化编程
人工智能
意图共鸣14 小时前
意图共鸣科技《认知智能白皮书》——感知与执行分离:认知架构(CA)如何重塑大模型底层结构
人工智能·架构
等一个人的@14 小时前
让数据自己开口:数睿通智库新增智能问数模块
人工智能·自然语言处理
ZGi.ai14 小时前
人工审查节点:让自动化工作流多一步人工把关
运维·人工智能·自动化·人机协同·智能体工作流·人工审查
王莎莎-MinerU15 小时前
MinerU 深度技术解析:从架构原理到生产部署的全面指南
css·人工智能·自然语言处理·架构·ocr·个人开发
盘古信息IMS15 小时前
盘古信息IMS V6 8.0重磅发布:以薪火AI数智平台点燃离散制造数智化引擎
大数据·人工智能·制造
weilaieqi115 小时前
从音响制造到AI家庭娱乐生态:不见不散AI智能K歌音响亮相第二十届深圳国际金融博览会
人工智能·制造·娱乐