机器视觉学习-day09-图像矫正

1 仿射变换与透视变换

1.1 仿射变换

之前在图像旋转实验中已经接触过仿射变换,仿射变换是一个二维坐标系到另一个二维坐标系的过程,在仿射变换中符合直线的平直性和平行性。

1.2 透视变换

透视变换是把一个图像投影到一个新的视平面的过程。在现实世界中,观察到的物体在人类视觉中都会受到透视效果的影响:近大远小。通俗的讲,透视变换的作用是改变物体被观察的视角。

实际开发中判断是否是透视变换的方法非常简单:只要是摄像头拍摄出的画面都是符合透视变换。

1.3 透视变换矩阵

与仿射变换相同,透视变换也有对应的透视变换矩阵,在这个过程原始图像src中的点(x,y)通过透视变换被转换到到dst图像中的新坐标点(x',y')

代码运行步骤:

图片输入→坐标选取→获取透视变换矩阵→透视变换→插值方法→边缘填充→图片输出

原始图片:4.jpg

python 复制代码
import cv2  # 导入OpenCV库,用于计算机视觉任务
import numpy as np  # 导入NumPy库,用于数值计算和数组操作
import matplotlib.pyplot as plt

if __name__ == '__main__':
    # 1. 图片输入
    path = '4.jpg'  # 定义图片路径
    image_np = cv2.imread(path)  # 读取图片,返回NumPy数组格式的图像数据

    # 2. 坐标选取
    # 左上、右上、左下、右下
    points = [[171, 5], [271, 105], [27, 150], [127, 248]]
    # 转换为np数组
    pts1 = np.float32(points)  # src的四个角点:将点列表转换为NumPy数组,数据类型为32位浮点数
    print(pts1)  # 打印点坐标
    print(type(pts1))  # 打印数据类型

    # 画红框,标记ROI区域
    image_line = image_np.copy()  # 创建原图的副本,避免修改原图

    # 画四条线,标记出要校正的区域
    cv2.line(
        image_line,  # 在哪个图像上画线
        points[0],  # 起点
        points[1],  # 终点
        (0, 0, 255),  # 颜色(B,G,R格式),这里是红色
        2,  # 线条粗细
        cv2.LINE_AA  # 抗锯齿线型,使线条更平滑
    )
    # 重复画线操作,连接其他点形成四边形
    cv2.line(image_line, points[1], points[3], (0, 0, 255), 2, cv2.LINE_AA)
    cv2.line(image_line, points[2], points[3], (0, 0, 255), 2, cv2.LINE_AA)
    cv2.line(image_line, points[0], points[2], (0, 0, 255), 2, cv2.LINE_AA)

    # 3. 获取透视变换矩阵
    # 获得原图分辨率,这个原图分辨率是后面定义矫正后的图片分辨率大小。
    # img_shape = image_np.shape  # 获取图像形状(高度, 宽度, 通道数)
    # print("原图分辨率:", img_shape)
    img_shape = (260, 170, 3)  # 可自行定义图像形状(高度, 宽度, 通道数)

    # 定义目标点:左上、右上、左下、右下 - 对应整个图像的四个角
    points = [[0, 0], [img_shape[1], 0], [0, img_shape[0]], [img_shape[1], img_shape[0]]]
    print(points)  # 打印目标点坐标
    # 转换为np数组
    pts2 = np.float32(points)  # dst的四个角点:将目标点转换为NumPy数组

    # 生成透视变换矩阵
    M = cv2.getPerspectiveTransform(
        pts1,  # src的四个角点: 源图像的四个角点(要校正的区域)
        pts2   # dst的四个角点: 源图像的四个角点(要校正的区域)
    )
    print(M)  # 打印透视变换矩阵

    # 4. 透视变换 + 5. 插值方法 + 6. 边缘填充
    correct_image = cv2.warpPerspective(
        image_np,  # 原图
        M,  # 透视变换矩阵
        (img_shape[1], img_shape[0]),  # dst分辨率:输出图像尺寸(宽度, 高度)
        cv2.INTER_LINEAR,  # 插值方法:双线性插值,平衡速度和质量
        cv2.BORDER_WRAP  # 边缘填充:边缘像素环绕
    )

    # 使用matplotlib手动去看要截取的x,y的数组参数
    q = plt.imread(path)
    plt.imshow(q)
    plt.axis('off')  # 取消坐标轴显示
    plt.show()

    # 7. 图片输出
    cv2.imshow('image_line', image_line)  # 显示带有标记线的图像
    cv2.imshow('correct_image', correct_image)  # 显示校正后的图像
    cv2.waitKey(0)  # 等待键盘输入,0表示无限等待
    cv2.imwrite('jz.png', correct_image)

运行结果:

相关推荐
九年义务漏网鲨鱼21 小时前
等效学习率翻倍?梯度累积三连坑:未除以 accum_steps、调度器步进错位、梯度裁剪/正则标度错误(含可复现实验与修复模板)
python·深度学习·学习
未来之窗软件服务1 天前
自己写算法(五)CryptoJS 前端学习——东方仙盟练气期
学习·算法·仙盟创梦ide·东方仙盟·东方仙盟加密
向阳花开_miemie1 天前
Android音频学习(十九)——音频HAL层简介
学习
木木子99991 天前
MongoDB集合学习笔记
笔记·学习·mongodb
Nan_Shu_6141 天前
学习:uniapp全栈微信小程序vue3后台 (25)
前端·学习·微信小程序·小程序·uni-app
darkb1rd1 天前
命令注入(Command Injection)漏洞学习笔记
笔记·学习
charlie1145141911 天前
Chrome 学习小记5——demo:(动态壁纸基础)
chrome·windows·学习
weixin_377634841 天前
【大模型-金融】Trading-R1 多阶段课程学习
学习·金融
今天也好累1 天前
贪心算法之会议安排问题
c++·笔记·学习·算法·贪心算法
无敌的大魔王1 天前
学习Java遇到的一些问题
学习