当前位置: 首页 > news >正文

图像处理基础篇-镜像仿射透视

一.图像镜像

图像镜像是图像旋转变换的一种特殊情况,通常包括垂直方向和水平方向的镜像。水平镜像通常是以原图像的垂直中轴为中心,将图像分为左右两部分进行堆成变换。如图7-1所示:

在这里插入图片描述

垂直镜像通常是以原图像的水平中轴线为中心,将图像划分为上下两部分进行堆成变换的过程,示意图如图7-2所示。

在这里插入图片描述

在Python中主要调用OpenCV的flip()函数实现图像镜像变换,函数原型如下:

  • dst = cv2.flip(src, flipCode)
    – src表示原始图像
    – flipCode表示翻转方向,如果flipCode为0,则以X轴为对称轴翻转,如果fliipCode>0则以Y轴为对称轴翻转,如果flipCode<0则在X轴、Y轴方向同时翻转。

下面代码是实现三个方向的翻转。

# -*- coding:utf-8 -*-
# By:Eastmount
import cv2  
import numpy as np
import matplotlib.pyplot as plt#读取图片
img = cv2.imread('scenery.png')
src = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#图像翻转
img1 = cv2.flip(src, 0)   #参数=0以X轴为对称轴翻转 
img2 = cv2.flip(src, 1)   #参数>0以Y轴为对称轴翻转
img3 = cv2.flip(src, -1)  #参数<0以X轴和Y轴翻转#显示图形
titles = ['Source', 'Image1', 'Image2', 'Image3']
images = [src, img1, img2, img3]
for i in range(4):plt.subplot(2,2,i+1), plt.imshow(images[i], 'gray')plt.title(titles[i])plt.xticks([]),plt.yticks([])
plt.show()

输出结果如图7-3所示,图中“Source”为原始图像,“Image1”为以X轴为对称轴翻转或垂直镜像,“Image2”为以Y轴为对称轴翻转或水平镜像,“Images3”为以X轴和Y轴翻转。

在这里插入图片描述


二.图像仿射

图像仿射变换又称为图像仿射映射,是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间。通常图像的旋转加上拉升就是图像仿射变换,仿射变换需要一个M矩阵实现,但是由于仿射变换比较复杂,很难找到这个M矩阵,OpenCV提供了根据变换前后三个点的对应关系来自动求解M的函数:

  • cv2.getAffineTransform(pos1,pos2)

其中pos1和pos2表示变换前后的对应位置关系,输出的结果为仿射矩阵M,接着使用函数cv2.warpAffine()实现图像仿射变换。图7-4是仿射变换的前后效果图。

在这里插入图片描述

图像仿射变换的函数原型如下:

  • M = cv2.getAffineTransform(pos1,pos2)
    – pos1表示变换前的位置
    – pos2表示变换后的位置

  • cv2.warpAffine(src, M, (cols, rows))
    – src表示原始图像
    – M表示仿射变换矩阵
    – (rows,cols)表示变换后的图像大小,rows表示行数,cols表示列数

实现代码如下所示:

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2
import numpy as np
import matplotlib.pyplot as plt#读取图片
src = cv2.imread('scenery.png')#获取图像大小
rows, cols = src.shape[:2]#设置图像仿射变换矩阵
pos1 = np.float32([[50,50], [200,50], [50,200]])
pos2 = np.float32([[10,100], [200,50], [100,250]])
M = cv2.getAffineTransform(pos1, pos2)#图像仿射变换
result = cv2.warpAffine(src, M, (cols, rows))#显示图像
cv2.imshow("original", src)
cv2.imshow("result", result)#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果如图7-5所示:

在这里插入图片描述


三.图像透视

图像透视变换(Perspective Transformation)的本质是将图像投影到一个新的视平面,同理OpenCV通过函数cv2.getPerspectiveTransform(pos1,pos2)构造矩阵M,其中pos1和pos2分别表示变换前后的4个点对应位置。得到M后在通过函数cv2.warpPerspective(src,M,(cols,rows))进行透视变换。

图像透视变换的函数原型如下:

  • M = cv2.getPerspectiveTransform(pos1, pos2)
    – pos1表示透视变换前的4个点对应位置
    – pos2表示透视变换后的4个点对应位置

  • cv2.warpPerspective(src,M,(cols,rows))
    – src表示原始图像
    – M表示透视变换矩阵
    – (rows,cols)表示变换后的图像大小,rows表示行数,cols表示列数

假设现在存在一张A4纸图像,现在需要通过调用图像透视变换校正图像。

在这里插入图片描述

图像透视变换的校正代码如下所示,代码中pos1表示透视变换前A4纸的四个顶点,pos2表示透视变换后A4纸的四个顶点。

# -*- coding: utf-8 -*-
# By:Eastmount
import cv2
import numpy as np
import matplotlib.pyplot as plt#读取图片
src = cv2.imread('transform.jpg')#获取图像大小
rows, cols = src.shape[:2]#设置图像透视变换矩阵
pos1 = np.float32([[114, 82], [287, 156], [8, 322], [216, 333]])
pos2 = np.float32([[0, 0], [188, 0], [0, 262], [188, 262]])
M = cv2.getPerspectiveTransform(pos1, pos2)#图像透视变换
result = cv2.warpPerspective(src, M, (190, 272))#显示图像
cv2.imshow("original", src)
cv2.imshow("result", result)#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()

最终输出结果如图7-7所示,它将图形校正显示。

在这里插入图片描述


四.总结

本章主要讲解Python和OpenCV的图像几何变换,详细介绍了图像镜像、图像仿射和图像透视,包括歪曲图像纠正的案例,希望大家喜欢。此外,这些知识点也是我们PC端或手机端图像处理应用常见的算法,读者可以尝试结合这些应用完成一套图像处理软件。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • jmeter 梯度测试 如何查看TPS、RT指标
  • 基于单片机的多功能电子钟设计
  • 一个进程的情况下,例如 tomcat 只启动一个项目,cpu 很高,倒是内存很低,是什么原因呢?
  • Kotlin 流 Flow
  • 安装win7鼠标键盘不能动原因分析及解决办法
  • Unity3D在2D游戏中获取触屏物体的方法
  • Spring Boot-自定义banner
  • ASP.NET Core 入门教学十七 GraphQL入门指南
  • 触想内嵌式工业一体机应用于智能检票机改善旅游体验
  • How can I provide a RGBA png file to OpenAI PHP library
  • 【LeetCode】07.整数反转
  • 系统架构师考试学习笔记第三篇——架构设计高级知识(18)面向服务架构设计理论与实践
  • DFS算法专题(一)——二叉树中的深搜【回溯与剪枝的初步注入】
  • 分类预测|基于蜣螂优化极限梯度提升决策树的数据分类预测Matlab程序DBO-Xgboost 多特征输入单输出 含基础模型
  • MySQL 默认事务隔离级别及原因
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • 2017 前端面试准备 - 收藏集 - 掘金
  • Android交互
  • Angular 4.x 动态创建组件
  • canvas绘制圆角头像
  • express + mock 让前后台并行开发
  • iOS 颜色设置看我就够了
  • JSDuck 与 AngularJS 融合技巧
  • js操作时间(持续更新)
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • Shell编程
  • 关于Java中分层中遇到的一些问题
  • 基于 Babel 的 npm 包最小化设置
  • 聊一聊前端的监控
  • 我看到的前端
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • 转载:[译] 内容加速黑科技趣谈
  • 《天龙八部3D》Unity技术方案揭秘
  • 阿里云移动端播放器高级功能介绍
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • # 利刃出鞘_Tomcat 核心原理解析(七)
  • #php的pecl工具#
  • #Spring-boot高级
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (k8s)Kubernetes本地存储接入
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (ros//EnvironmentVariables)ros环境变量
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (四)React组件、useState、组件样式
  • (详细文档!)javaswing图书管理系统+mysql数据库
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .Net mvc总结
  • .NET 中 GetProcess 相关方法的性能
  • .net反编译的九款神器
  • .Net通用分页类(存储过程分页版,可以选择页码的显示样式,且有中英选择)