OpenCV学习之路(五)图像的几何变换

标签: OpenCV学习之路

在这一章将要学习图像的移动、旋转,仿射变换等

扩展缩放

我们如果想要改变图像的大小,我们就需要对图像进行扩展缩放,opencv提供给我们控制扩展缩放的函数:

cv2.resize(src, dst, interpolation=CV_INTER_LINEAR)

参数解释:

  • src:进行扩展缩放的原图片
  • dst:可以在此处设置缩放因子,也可手动设置尺寸
  • interpolation:在缩放时我们推荐使用cv2.INTER_AREA, 在扩展时我们推荐使用cv2.INTER_CUBIC(慢) 和 cv2.INTER_LINEAR。 默认情况下所有改变图像尺寸大小的操作使用的插值方法都是cv2.INTER_LINEAR。
import numpy as np
import cv2
img=cv2.imread('D://zopencv//test1.png')
#因为我们此处设置了缩放因子,所以第二个参数为None
img1=cv2.resize(img,None,fx=2,fy=2,interpolation=cv2.INTER_LINEAR)
#直接手动设置尺寸
length=img.shape[0]
width=img.shape[1]
img2=cv2.resize(img,(2*width,2*length),interpolation=cv2.INTER_LINEAR)
img3=cv2.resize(img,None,fx=0.5,fy=0.5,interpolation=cv2.INTER_AREA)
while(1):
    cv2.imshow('image1', img1)
    cv2.imshow('image2', img2)
    cv2.imshow('image3',img3)
    if cv2.waitKey(1)&0xFF==27:
        break
cv2.destroyAllWindows()

平移

使用函数:

cv2.warpAffine()

平移就是将对象换一个位置。如果你要沿(x,y)方向移动,移动的距离 是(tx,ty),你可以以下面的方式构建移动矩阵:
在这里插入图片描述
你可以使用 Numpy 数组构建这个矩阵(数据类型是 np.float32),然 后把它传给函数 cv2.warpAffine()。

import numpy as np
import cv2
img=cv2.imread('D://zopencv//test1.png',0)
length,width=img.shape[:2]
m=np.float32([[1,0,10],[0,1,5]])#构造矩阵
img1=cv2.warpAffine(img,m,(width,length))
#函数 cv2.warpAffine() 的第三个参数的是输出图像的大小,它的格式 应该是图像的(宽,高)。应该记住的是图像的宽对应的是列数,高对应的是行 数。
cv2.imshow('image',img1)
cv2.waitKey(0)
cv2.destroyAllWindows()

旋转

旋转也需要构建相应的旋转矩阵,但是opencv中简化了,用一个函数即可代替构建旋转矩阵的操作。

cv2.getRotationMatrix2D()

函数接受三个参数

  • 第一个参数为旋转中心
  • 第二个为旋转角度
  • 第三个为旋转后的缩放因子
M=cv2.getRotationMatrix2D((cols/2,rows/2),90,1)
#第三个参数为输出图像的尺寸中心
dst=cv2.warpAffine(img,M,(cols,rows))

仿射变换

仿射变换中,原图中所有的平行线在结果图像中同样平行。为了创建这 个矩阵我们需要从原图像中找到三个点以及他们在输出图像中的位置。然后 cv2.getAffineTransform 会创建一个 2x3 的矩阵,最后这个矩阵会被传给 函数 cv2.warpAffine。
实际上就是从原图选出三个点,我认为最好选三个不在一条线上的点,因为这三个点可以确定一个平面。2*3矩阵第一行是你找的三个点的坐标,第二行是变幻后的三个点坐标。

import cv2 
import numpy as np 
from matplotlib import pyplot as plt
img=cv2.imread('drawing.png')
 rows,cols,ch=img.shape
pts1=np.float32([[50,50],[200,50],[50,200]]) 
pts2=np.float32([[10,100],[200,50],[100,250]])
M=cv2.getAffineTransform(pts1,pts2)
dst=cv2.warpAffine(img,M,(cols,rows))
plt.subplot(121,plt.imshow(img),plt.title('Input')) 
plt.subplot(121,plt.imshow(img),plt.title('Output')) 
plt.show()
代码来自OpenCV用户手册,段立辉译

在这里插入图片描述

透视变幻

对于视角变换,我们需要一个 3x3 变换矩阵。在变换前后直线还是直线。 要构建这个变换矩阵,你需要在输入图像上找 4 个点,以及他们在输出图 像上对应的位置。这四个点中的任意三个都不能共线。这个变换矩阵可以有 函数 cv2.getPerspectiveTransform() 构建。然后把这个矩阵传给函数 cv2.warpPerspective。
与仿射变换的办法差不多,二者有相似之处,不过透视变换需要四个点的位置,也就是一个2*4矩阵。

import cv2 
import numpy as np
 from matplotlib import pyplot as plt
img=cv2.imread('sudokusmall.png') 
rows,cols,ch=img.shape
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M=cv2.getPerspectiveTransform(pts1,pts2)
dst=cv2.warpPerspective(img,M,(300,300))
plt.subplot(121,plt.imshow(img),plt.title('Input')) plt.subplot(121,plt.imshow(img),plt.title('Output')) 
plt.show()
#代码来自opencv用户手册,段立辉译

在这里插入图片描述

版权声明:本文为weixin_45939019原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45939019/article/details/104347073

智能推荐

【Sublime】使用 Sublime 工具时运行python文件

使用 Sublime 工具时报Decode error - output not utf-8解决办法   在菜单中tools中第四项编译系统 内最后一项增添新的编译系统 自动新建 Python.sublime-build文件,并添加"encoding":"cp936"这一行,保存即可 使用python2 则注释encoding改为utf-8 ctr...

java乐观锁和悲观锁最底层的实现

1. CAS实现的乐观锁 CAS(Compare And Swap 比较并且替换)是乐观锁的一种实现方式,是一种轻量级锁,JUC 中很多工具类的实现就是基于 CAS 的,也可以理解为自旋锁 JUC是指import java.util.concurrent下面的包, 比如:import java.util.concurrent.atomic.AtomicInteger; 最终实现是汇编指令:lock...

Python 中各种imread函数的区别与联系

  原博客:https://blog.csdn.net/renelian1572/article/details/78761278 最近一直在用python做图像处理相关的东西,被各种imread函数搞得很头疼,因此今天决定将这些imread总结一下,以免以后因此犯些愚蠢的错误。如果你正好也对此感到困惑可以看下这篇总结。当然,要了解具体的细节,还是应该 read the fuc...

用栈判断一个字符串是否平衡

注: (1)本文定义:左符号:‘(’、‘[’、‘{’…… 右符号:‘)’、‘]’、‘}’……. (2)所谓的字符串的符号平衡,是指字符串中的左符号与右符号对应且相等,如字符串中的如‘(&r...

JAVA环境变量配置

位置 计算机->属性->高级系统设置->环境变量 方式一 用户变量新建path 系统变量新建classpath 方式二 系统变量 新建JAVA_HOME,值为JDK路径 编辑path,前加 方式三 用户变量新建JAVA_HOME 此路径含lib、bin、jre等文件夹。后运行tomcat,eclipse等需此变量,故最好设。 用户变量编辑Path,前加 系统可在任何路径识别jav...

猜你喜欢

常用的伪类选择器

CSS选择器众多 CSS选择器及权重计算 最常用的莫过于类选择器,其它的相对用的就不会那么多了,当然属性选择器和为类选择器用的也会比较多,这里我们就常用的伪类选择器来讲一讲。 什么是伪类选择器? CSS伪类是用来添加一些选择器的特殊效果。 常用的为类选择器 状态伪类 我们中最常见的为类选择器就是a标签(链接)上的为类选择器。 当我们使用它们的时候,需要遵循一定的顺序问题,否则将可能出现bug 注意...

ButterKnife的使用介绍及原理探究(六)

前面分析了ButterKnife的源码,了解其实现原理,那么就将原理运用于实践吧。 github地址:       点击打开链接 一、自定义注解 这里为了便于理解,只提供BindView注解。 二、添加注解处理器 添加ViewInjectProcessor注解处理器,看代码, 这里分别实现了init、getSupportedAnnotationTypes、g...

1.写一个程序,提示输入两个字符串,然后进行比较,输出较小的字符串。考试复习题库1|要求:只能使用单字符比较操作。

1.写一个程序,提示输入两个字符串,然后进行比较,输出较小的字符串。 要求只能使用单字符比较操作。 参考代码: 实验结果截图:...

小demo:slideDown()实现二级菜单栏下拉效果

效果如下,鼠标经过显示隐藏的二级菜单栏 但是这样的时候会存在一个问题,就是鼠标快速不停移入移出会导致二级菜单栏闪屏现象,一般需要使用stop()来清除事件  ...

基于docker环境的mysql主从复制

1、安装docker 可以参考之前的博客,之前写过了~ 2、拉取mysql镜像 3、创建mysql01和mysql02实例 主: 从: 4、进入容器修改配置 1)修改主数据库配置 进入主数据库容器 切换到 etc/mysql/目录下 查看可以看到my.cnf文件,使用vim编辑器打开,但是需要提前安装 安装vim命令: 安装成功后,修改my.cnf文件 新增配置后的my.cnf: binlog 日...