【OpenCV实现图像:使用OpenCV进行图像处理之透视变换】
文章目录
- 概要
- 计算公式
- 举个栗子
- 实际应用
- 小结
概要
透视变换(Perspective Transformation)是一种图像处理中常用的变换手段,它用于将图像从一个视角映射到另一个视角,常被称为投影映射。透视变换可以用于矫正图像中的透视畸变,使得图像中的物体在新的视平面上呈现更加规则的形状。
透视变换通常涉及到寻找图像中的特定点集,这些点对应于真实场景中的特定位置。通过这些点的映射关系,可以计算出透视变换的矩阵,然后将整个图像进行变换。在实际应用中,透视变换常用于校准摄像头、图像矫正、虚拟增强现实等领域。
计算公式
一般来说,通用的图像变换公式如下所示:

上述公式中,u,v代表原始图像坐标,x,y为经过透视变换的图片坐标,其中变换矩阵为3X3形式。进而可以得到:

举个栗子

直观的来看,透视变换的作用就是将左侧图像的坐标点
[[50,0],[150,0],[0,200],[200,200]]
转化为新的坐标
[[0,0],[200,0],[0,200],[200,200]]
通过计算我们知道,转换矩阵如下

采用左上角的点(50,0)代入公式,

接着将列向量的前两维度除以第三维执行归一化:

所以原图左上角点执行透视变换后的映射关系:

实际应用
1)读入图像
首先我们来读入一副彩色图像,如下:
import cv2
import numpy as npimg = cv2.imread("image/sample.jpg")
h, w, c = img.shape # 获取图像的高度、宽度和通道数
2)挑选原图四个点
接着我们需要挑选四个点,我们这里采用左上,左下,右下和右上,下面的代码把我们挑选的四个点画到图像上.
src_list = [(61, 70), (151, 217), (269, 143), (160, 29)]# 在图像上标出四个点
for i, pt in enumerate(src_list):cv2.circle(img, pt, 5, (0, 0, 255), -1)cv2.putText(img, str(i+1), (pt[0]+5, pt[1]+10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)# 将挑选的四个点转换为NumPy数组
pts1 = np.float32(src_list)
3)显示图像:
cv2.imshow('Original Image with Selected Points', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
完整代码:
import cv2
import numpy as npimg = cv2.imread("img_5.png")
h, w, c = img.shape # 获取图像的高度、宽度和通道数
src_list = [(61, 70), (151, 217), (269, 143), (160, 29)]# 在图像上标出四个点
for i, pt in enumerate(src_list):cv2.circle(img, pt, 5, (0, 0, 255), -1)cv2.putText(img, str(i+1), (pt[0]+5, pt[1]+10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)# 将挑选的四个点转换为NumPy数组
pts1 = np.float32(src_list)
cv2.imshow('Original Image with Selected Points', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

以上四个点标注位置不对,所以需要改变点的位置.

4)进行透视变换
首先选择四个目的图像上的点,然后调用openv函数进行透视变换.
pts2 = np.float32([[0, 0], [0, w - 2], [h - 2, w - 2], [h - 2, 0]])
matrix = cv2.getPerspectiveTransform(pts1, pts2)
result = cv2.warpPerspective(img, matrix, (h, w))
cv2.imshow("Image", img)
cv2.imshow("Perspective transformation", result)
cv2.waitKey(0)
全部
import cv2
import numpy as npimg = cv2.imread("img_5.png")
h, w, c = img.shape # 获取图像的高度、宽度和通道数
src_list = [(81, 325), (105, 580), (590, 340), (480, 110)]# 在图像上标出四个点
for i, pt in enumerate(src_list):cv2.circle(img, pt, 5, (0, 0, 255), -1)cv2.putText(img, str(i+1), (pt[0]+5, pt[1]+10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)# 将挑选的四个点转换为NumPy数组
pts1 = np.float32(src_list)# 选择目标图像上的四个点
pts2 = np.float32([[0, 0], [0, w - 2], [h - 2, w - 2], [h - 2, 0]])# 计算透视变换矩阵
matrix = cv2.getPerspectiveTransform(pts1, pts2)# 应用透视变换
result = cv2.warpPerspective(img, matrix, (w, h)) # 修正图像大小# 显示原始图像、透视变换前后的图像
cv2.imshow("Original Image with Selected Points", img)
cv2.imshow("Perspective Transformation", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

小结
使用OpenCV中的透视变换的基本步骤:
找到四个特定的点:
在原始图像中选择四个特定的点,这四个点对应于一个矩形或者平行四边形在真实场景中的投影。
计算透视变换矩阵:
利用这四个点的映射关系,计算透视变换矩阵。OpenCV提供了 cv2.getPerspectiveTransform 函数来实现这一步骤。
应用透视变换:
利用计算得到的透视变换矩阵,对整个图像进行透视变换。OpenCV提供了 cv2.warpPerspective 函数用于执行透视变换。
相关文章:
【OpenCV实现图像:使用OpenCV进行图像处理之透视变换】
文章目录 概要计算公式举个栗子实际应用小结 概要 透视变换(Perspective Transformation)是一种图像处理中常用的变换手段,它用于将图像从一个视角映射到另一个视角,常被称为投影映射。透视变换可以用于矫正图像中的透视畸变&…...
Vue中学习笔记-数据代理
文章目录 前文提要数据代理的概念MVVM模型和Vue中的数据代理M,模型V,视图VM,视图模型 前文提要 本人仅做个人学习记录,如有错误,请多包涵 数据代理的概念 使用一个对象代理对另一个对象中属性的操作。 MVVM模型和Vu…...
IDEA 配置maven结合案例使用篇
1. 项目需求和结构分析 需求案例:搭建一个电商平台项目,该平台包括用户服务、订单服务、通用工具模块等。 项目架构: 用户服务:负责处理用户相关的逻辑,例如用户信息的管理、用户注册、登录等。 spring-context 6.0.…...
基于白鲸算法优化概率神经网络PNN的分类预测 - 附代码
基于白鲸算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于白鲸算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于白鲸优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要:针对PNN神经网络的光滑…...
Android使用Kotlin利用Gson解析多层嵌套Json数据
文章目录 1、依赖2、解析 1、依赖 build.gradle(app)中加入 dependencies { implementation com.google.code.gson:gson:2.8.9 }2、解析 假设这是要解析Json数据 var responseStr "{"code": 200,"message": "操作成功","data&quo…...
DOM事件的传播机制
DOM事件的传播机制是指当一个事件在DOM树中触发时,它是如何在各个元素之间传播的。DOM事件传播机制分为三个阶段:捕获阶段、目标阶段和冒泡阶段。此外,还有一种常用的技术称为事件委托,它能够简化事件处理程序的绑定和管理。本文将…...
gitlab利用CI多工程持续构建
搭建CI的过程中有多个工程的时候,一个完美的构建过程往往是子工程上的更新(push 或者是merge)触发父工程的构建,这就需要如下建立一个downstream pipeline 子仓库1 .gitlab-ci.yml stages:- buildbuild_job:stage: buildtrigger:project: test_user/tes…...
【C++初阶】四、类和对象(构造函数、析构函数、拷贝构造函数、赋值运算符重载函数)
相关代码gitee自取: C语言学习日记: 加油努力 (gitee.com) 接上期: 【C初阶】三、类和对象 (面向过程、class类、类的访问限定符和封装、类的实例化、类对象模型、this指针) -CSDN博客 引入:类的六个默认成员函数…...
js粒子效果(二)
效果: 代码: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Particle Animation</title><…...
01.让自己习惯C++
让自己习惯C 条款1:视C为一个语言联邦 条款1中提到了将C看作为一个“语言联邦”的概念。具体来说,“语言联邦”是指将C看作由多种不同的子语言组成的联邦。每种子语言都有自己的惯用法、工具和库,可以用来解决特定的问题。因此,…...
ElementUI table+dialog实现一个简单的可编辑的表格
table组件如何实现可编辑呢? 我的需求是把table组件那样的表格,实现它点击可以弹出一个框,然后在这个框里面输入你的东西,然后将他回显回去,当然,输入的有可能是时间啥的。 为什么要弹出弹层不在框上直接…...
Rust语言精讲:数据类型全解析
大家好!我是lincyang。 今天,我们将深入探讨Rust语言中的数据类型,这是理解和掌握Rust的基础。 Rust语言数据类型概览 Rust是静态类型语言,所有变量类型在编译时确定。Rust的数据类型分为两类:标量类型和复合类型。…...
《数据结构、算法与应用C++语言描述》-代码实现散列表(线性探查与链式散列)
散列表 完整可编译运行代码:Github:Data-Structures-Algorithms-and-Applications/_22hash/ 定义 字典的另一种表示方法是散列(hashing)。它用一个散列函数(也称哈希函数)把字典的数对映射到一个散列表(…...
Hadoop学习笔记:运行wordcount对文件字符串进行统计案例
文/朱季谦 我最近使用四台Centos虚拟机搭建了一套分布式hadoop环境,简单模拟了线上上的hadoop真实分布式集群,主要用于业余学习大数据相关体系。 其中,一台服务器作为NameNode,一台作为Secondary NameNode,剩下两台当…...
python编写简单登录系统(密码混淆加密)
输入非123的数字会显示输入123选项,输入空格或者回车会报错,因为choice设置成int型先输入2个正常账户进去预防了用户名为空,密码为空或者小于3个,用户名已存在3种情况只有用户名和对应的密码都输入正确才能登录成功输入选项3退出代…...
UVA1025 城市里的间谍 A Spy in the Metro
UVA1025 城市里的间谍 A Spy in the Metro 题面翻译 题目大意 某城市地铁是一条直线,有 n n n( 2 ≤ n ≤ 50 2\leq n\leq 50 2≤n≤50)个车站,从左到右编号 1 … n 1\ldots n 1…n。有 M 1 M_1 M1 辆列车从第 1 1 1 站开…...
【科普知识】什么是步进电机?
德国百格拉公司于1973年发明了五相混合式步进电机及其驱动器,1993年又推出了性能更加优越的三相混合式步进电机。我国在80年代以前,一直是反应式步进电机占统治地位,混合式步进电机是80年代后期才开始发展。 步进电机是一种用电脉冲信号进行…...
AWS云服务器EC2实例实现ByConity快速部署
1. 前言 亚马逊是全球最大的在线零售商和云计算服务提供商。AWS云服务器在全球范围内都备受推崇,被众多业内人士誉为“云计算服务的行业标准”。在国内,亚马逊AWS也以其卓越的性能和服务满足了众多用户的需求,拥有着较高的市场份额和竞争力。…...
Docker的项目资源参考
Docker的项目资源包括以下内容: Docker官方网站:https://www.docker.com/ Docker Hub:https://hub.docker.com/ Docker文档:https://docs.docker.com/ Docker GitHub仓库:https://github.com/docker Docker官方博客…...
wsl-ubuntu 系统端口总被主机端口占用问题解决
wsl-ubuntu 系统端口总被主机端口占用问题解决 0. 问题描述1. 解决方法 0. 问题描述 wsl-ubuntu 子系统中的服务,总是启动失败,错误信息是端口被占用。 用一些命令查看,被占用的端口也没有用服务启动。 1. 解决方法 运行, ne…...
哔咔漫画下载器:高性能多线程下载引擎深度解析
哔咔漫画下载器:高性能多线程下载引擎深度解析 【免费下载链接】picacomic-downloader 哔咔漫画 picacomic pica漫画 bika漫画 PicACG 多线程下载器,带图形界面 带收藏夹,已打包exe 下载速度飞快 项目地址: https://gitcode.com/gh_mirrors…...
Comsol介质超表面三次谐波非线性模型研究:倍频模型与转换效率计算文献赠予
Comsol介质超表面三次谐波非线性模型,包含功率依赖。 且倍频模型以及转换效率计算。打开COMSOL时总会被非线性光学模块的选项搞得头疼?今天咱们直接拿介质超表面的三次谐波模型开刀,聊聊如何让超薄结构产生高频光波。非线性效应这东西&#x…...
Android系统启动时,GPS HAL服务是如何拉起并加载gps.xxx.so驱动文件的?
Android GNSS HAL服务启动与GPS驱动加载全链路解析 当按下Android设备的电源键时,系统启动过程中有一个关键环节常被开发者忽视——GNSS HAL服务如何动态加载GPS硬件驱动。这背后隐藏着从init进程解析rc文件到HIDL接口初始化的精妙设计,更涉及Android硬件…...
在 SAP S/4HANA 里把经典事务 BP 挂进 Fiori,并支持参数传递
先把名字叫对,很多项目里说的 Transaction launcher,落到 SAP 官方对象上,其实是 tile 加 target mapping 在 SAP 官方术语里,真正负责把导航意图解析到目标应用的,不是一个孤立的 Transaction launcher 对象,而是 SAP Fiori launchpad 里的 target mapping。target map…...
ROS高效进阶第六章 -- 机器人自主导航实战:从move_base框架解析到多场景应用
1. move_base框架深度解析:机器人导航的"大脑" 第一次接触move_base时,我完全被它复杂的参数列表吓到了。但实际用下来发现,这个ROS导航核心框架就像乐高积木——模块化设计让每个功能都能单独调校。move_base本质上是个任务调度中…...
TUIOS磁带录制与自动化:终极指南——如何轻松录制和重放终端工作流程
TUIOS磁带录制与自动化:终极指南——如何轻松录制和重放终端工作流程 【免费下载链接】tuios Terminal UI OS (Terminal Multiplexer) 项目地址: https://gitcode.com/gh_mirrors/tu/tuios TUIOS(Terminal UI OS)是一款强大的终端复用…...
vedo性能优化指南:处理大规模3D数据的终极技巧
vedo性能优化指南:处理大规模3D数据的终极技巧 【免费下载链接】vedo A python module for scientific analysis of 3D data based on VTK and Numpy 项目地址: https://gitcode.com/gh_mirrors/ve/vedo vedo是一个基于VTK和Numpy的Python模块,专…...
Oumuamua-7b-RP步骤详解:Web UI中调整Top-k=30提升角色专注度实操
Oumuamua-7b-RP步骤详解:Web UI中调整Top-k30提升角色专注度实操 1. 项目概述 Oumuamua-7b-RP 是一款专为日语角色扮演对话设计的Web界面大语言模型,基于Mistral-7B架构开发。这个工具特别适合想要体验沉浸式日语角色对话的用户,通过简单的…...
python ujson
最近有个同事在做一个高吞吐量的数据管道,里面大量的JSON序列化和反序列化操作。他用的是标准库的json模块,后来发现这块成了整个系统的瓶颈。后来换了ujson,性能直接翻了两三倍。这让我觉得自己也应该好好聊聊这个东西。 1. ujson是什么 ujs…...
企业财务数字化转型:从RPA到AI Agent的落地路径
在企业数字化转型中,财务一直是最优先落地的场景之一。原因很现实:流程标准、数据集中、效果可量化。但也正因为“好做”,很多企业对财务自动化的理解,长期停留在一个比较初级的阶段,随着AI能力的引入,财务…...
