1 仿射变换与透视变换

1.1 仿射变换

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

    1.2 透视变换

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

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

    1.3 透视变换矩阵

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

    代码运行步骤:

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

    原始图片:4.jpg

    import cv2  # 导入OpenCV库,用于计算机视觉任务
    import numpy as np  # 导入NumPy库,用于数值计算和数组操作
    import matplotlib.pyplot as pltif __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)
    

    运行结果:

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
    如若转载,请注明出处:http://www.pswp.cn/bicheng/95086.shtml
    繁体地址,请注明出处:http://hk.pswp.cn/bicheng/95086.shtml
    英文地址,请注明出处:http://en.pswp.cn/bicheng/95086.shtml

    如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    杰理ac791获取之前版本sdk

    很惭愧,一个如此简单的问题卡了这么久,运动战的本质就是多找线索,多尝试

    基于轴重转移补偿和多轴协调的粘着控制方法研究

    基于轴重转移补偿和多轴协调的粘着控制方法研究 1. 论文标题 基于轴重转移补偿和多轴协调的粘着控制方法研究 2. 内容概括 该论文针对重载电力机车在复杂轨面条件下易发生空转的问题,提出了一种新型粘着控制方法。传统方法仅考虑单轴粘着利用而忽略轴间关系,本文设计了包…

    台达 PLC 软件导入 EDS 文件后不能通过 PDO 控制的解决方法

    一、功能及注意事项 1.功能说明:通过修改 EDS 文件处理台达 PLC 软件导入 EDS 文件后不能通过 PDO 控制的解决方法 2.注意事项:1).此文档只针对立迈胜 CANopen 通讯一体化电机; 2).EDS 文件可以用记事本打开; 二、EDS 文件修改 IS…

    Python库2——Matplotlib2

    上一篇文章主要介绍了Matplotlib库中的Pyplot模块中几大常见图像的绘制,包括自行修改图像的属性,在绘制图像时会自动创建一个图形窗口来展现这些图像。本节内容继续讲讲这个(Figure)图像窗口即其一些常见用法。 其他python库链接…

    AI生成思维导图和AI生成Excel公式

    AI生成思维导图和AI生成Excel公式 AI 生成思维导图和 AI 生成 Excel 公式是一个完全免费的 AI 办公合集网站。 它完全免费,一个网站支持多个实用 AI 办公功能,包括:免费 AI Excel 公式生成器、输入 Excel 公式解释含义、AI Excel 助手、Exc…

    java中的VO、DAO、BO、PO、DO、DTO

    VO、DAO、BO 等对象在了解这里 po、vo、dao、之前先介绍下 MVC 开发模式M层负责与数据库打交道;C层负责业务逻辑的编写;V层负责给用户展示(针对于前后端不分离的项目,不分离项目那种编写模版的方式,理解V的概念更直观&…

    More Effective C++ 条款16:牢记80-20准则(Remember the 80-20 Rule)

    More Effective C 条款16:牢记80-20准则(Remember the 80-20 Rule)核心思想:软件性能优化遵循帕累托原则(Pareto Principle),即大约80%的性能提升来自于优化20%的关键代码。识别并专注于这些关键…

    Java中对泛型的理解

    一、泛型是什么?1. 定义: 泛型允许你在定义类、接口或方法时使用类型参数(Type Parameter)。在使用时(如声明变量、创建实例时),再用具体的类型实参(Type Argument) 替换…

    Redis开发06:使用stackexchange.redis库结合WebAPI对redis进行增删改查

    一、接口写法namespace WebApplication1.Controllers.Redis {[ApiController][Route("/api/[controller]")]public class RedisService : IRedisService{private readonly IConnectionMultiplexer _redis;//StackExchange.Redis库自带接口public RedisService(IConne…

    【前端教程】从零开始学JavaScript交互:7个经典事件处理案例解析

    在网页开发中,交互性是提升用户体验的关键。JavaScript作为网页交互的核心语言,通过事件处理机制让静态页面"动"了起来。本文将通过7个经典案例,从简单到复杂,逐步讲解JavaScript事件处理的实现方法和应用场景。 案例1&…

    内存模型(Memory Model)是什么?

    内存模型(Memory Model)是什么? 内存模型是一个非常深刻且核心的计算机科学概念。 核心摘要 内存模型是一个契约或协议,它精确定义了: 一个线程对共享内存的写操作,如何以及何时对其他线程可见。 内存操作(读/写)可以被重新排序的程度。 它连接了硬件(CPU如何执行指令…

    在 MyBatis 中oracle基本数值类型的 JDBC 类型映射

    基本数值类型的 JDBC 类型Java 类型JDBC 类型 (jdbcType)说明int / IntegerINTEGER标准整数类型long / LongBIGINT大整数类型short / ShortSMALLINT小整数类型float / FloatFLOAT单精度浮点数double / DoubleDOUBLE双精度浮点数java.math.BigDecimalDECIMAL高精度小数&#xff…

    Spring注解演进与自动装配原理深度解析:从历史发展到自定义Starter实践

    目录 Spring注解发展史 Spring 1.X Spring 2.X Spring 2.5之前 Required Repository Aspect Spring2.5 之后 Spring 3.x ComponentScan Import 静态导入 ImportSelector ImportBeanDefinitionRegistrar EnableXXX Spring 4.x Spring 5.x 什么是SPI 自动装配…

    第三届机械工程与先进制造智能化技术研讨会(MEAMIT2025)

    【重要信息】 大会官网:https://www.yanfajia.com/action/p/BYE27DYDhttps://www.yanfajia.com/action/p/BYE27DYD 会议地点:哈尔滨理工大学 论文检索:EI Compendex、Scopus 还有部份版面,欲投稿从速,即将提交出版…

    笔记本电脑频繁出现 vcomp140.dll丢失怎么办?结合移动设备特性,提供适配性强的修复方案

    对于需要用电脑处理工作的人来说,“vcomp140.dll 丢失” 导致程序频繁闪退,无疑会严重影响工作效率。尝试重启电脑、重新安装软件后,问题依然存在,这时候该怎么办?别着急,vcomp140.dll 丢失看似棘手&#x…

    微动开关-电竞鼠标核心!5000万次寿命微动开关评测

    一、主流电竞微动开关技术对比‌光磁微动技术‌采用非接触式光学触发原理理论寿命突破5000万次触发响应速度0.2ms‌‌传统机械微动‌欧姆龙D2FC-F-7N系列5000万次标称寿命机械结构简单可靠‌‌创新结构微动‌双飞燕漆蓝荧光微动特殊涂层提升耐久性手感反馈独特‌二、5000万次寿…

    Go语言与Docker 开发的核心应用领域

    1. 容器化应用构建与部署‌‌轻量化镜像构建Go 语言编译生成静态二进制文件,结合多阶段构建的 Dockerfile,可大幅缩小镜像体积(例如使用 scratch 或 alpine 基础镜像),提升部署效率‌。示例 Dockerfile 片段&#xff1…

    【ESP32-IDF】网络连接开发2:Wi‑Fi 智能配网(SmartConfig)

    系列文章目录 持续更新… 文章目录系列文章目录前言一、Wi‑Fi 智能配网概述1.SmartConfig 简介2.SmartConfig 工作原理3.SmartConfig 协议类型二、Wi‑Fi 智能配网类型定义及相关API三、Wi‑Fi 智能配网示例程序总结前言 在物联网设备开发过程中,如果将 Wi-Fi 的…

    CVPR深度学习研究指南:特征提取模块仍是论文创新难点

    关注gongzhonghao【CVPR顶会精选】在深度学习赛道里,别只盯着堆模型卷参数了。最近不少高分工作都在打“可解释”这张牌,把原本难以理解的黑箱模型用轻量方法剖开,既能增强学术价值,还能拓展落地场景。更妙的是,这类研…

    redis----list详解

    列表(List)相当于数组或者顺序表一、通用命令LPUSH key value1 [value2 ...]在列表 key 的左侧(头部)插入一个或多个值。示例:LPUSH fruits apple banana → 列表变为 [banana, apple]LPUSHX 只有列表已存在时才会执行…