OpenCV+Python几何变换的实现示例

几何变换

图像的几何变换是指将一幅图像映射到另一幅图像内。有缩放、翻转、仿射变换、透视、重映射等操作。

1 缩放

使用cv2.resize()函数实现对图像的缩放,但要注意cv2.resize()函数内的dsize参数与原图像的行列属性是相反的,也就是:目标图像的行数是原始图像的列数,目标图像的列数是原始图像的行数。

下面举例说明cv2.resize()函数的用法:

import cv2
img=cv2.imread('E:/python_opencv/tupian.jpg')
rows,cols=img.shape[0:2]  #行数和列数等于img的长度和宽度
size=(int(cols*0.9),int(rows*0.5))  #比例:列变为原来0.9倍,行变为0.5倍
rst=cv2.resize(img,size)  #将img按size比例缩放
print('img.shape=',img.shape)
print('rst.shape=',rst.shape)

运行程序的结果如下:

img.shape=(600,60,3)
rst.shape=(300,54,3)

可以看出,行数变为原来的0.5倍,列数变为原来的0.9倍。代码中size的行列位置发生了交换。

2 翻转

使用cv2.flip()函数对图像翻转,能够实现水平方向翻转、垂直方向翻转、两个方向同时翻转。

下面举例说明cv2.flip()函数的用法:

import cv2
img=cv2.imread('E:/python_opencv/tupian.jpg')
x=cv2.flip(img,0)   #图x对原图像绕x轴翻转
y=cv2.flip(img,1)   #图y对原图像绕y轴翻转
xy=cv2.flip(img,-1)  #图xy对原图像绕x轴y轴同时翻转
cv2.imshow('img',img)
cv2.imshow('x',x)
cv2.imshow('y',y)
cv2.imshow('xy',xy)
cv2.waitKey()
cv2.destroyAllWindows()

程序运行结果如下四幅图,第一幅是原图,第二幅是绕x轴翻转,第三幅是绕y轴翻转,第四幅是绕x轴y轴同时翻转。

3 仿射

仿射变换是指图像实现平移、旋转等操作。

先设置一个变换矩阵M,然后使用cv2.warpAffine()函数对原图像和变换矩阵M进行仿射操作。

(一)平移

要实现图像的平移,我们先自定义一个转换矩阵,再进行仿射平移变换。例程如下:

import cv2
import numpy as np
img=cv2.imread('E:\python_opencv/tupian.jpg')
height,width=img.shape[:2]     #读取原图像的长和宽
x=100                      #自定义转换矩阵M的x轴移动值
y=200                      #自定义转换矩阵M的y轴移动值
M=np.float32([[1,0,x],[0,1,y]])    #构造转换矩阵M
move=cv2.warpAffine(img,M,(width,height))  #平移映射
cv2.imshow('orginal',img)
cv2.imshow('move',move)
cv2.waitKey()
cv2.destroyAllWindows()

程序运行结果如下图所示,左为原图,右为平移后的图。

(二)旋转

使用函数cv2.getRotationMatrix2D()获得转移矩阵M,然后使用函数cv2.warpAffine()进行仿射旋转变换。例程如下:

import cv2
img=cv2.imread('E:\python_opencv/tupian.jpg')
height,width=img.shape[:2]  #读取原图像的长和宽
M=cv2.getRotationMatrix2D((width/2,height/2),45,0.6)  #以中心为原点,逆时针旋转45°,且缩小为原图的0.6倍,获得转移矩阵M
rotate=cv2.warpAffine(img,M,(width,height))  #旋转映射
cv2.imshow('original',img)
cv2.imshow('rotation',rotate)
cv2.waitKey()
cv2.destroyAllWindows()

程序运行结果如下图所示,左为原图,右为旋转后的图。

4 透视

透视变换是指将矩阵图形投影到另一个视平面,可以映射为任意四边形,所以透视变换也被称为投影映射(ProjectionMapping),并不是字面意义上的“透视”。透视与上节的仿射不同,仿射可以将矩阵映射为任意平行四边形。

使用cv2.warpPerspective()函数实现透视变换。例程如下:

#完成图像透视
import cv2
import numpy as np
img=cv2.imread('E:/python_opencv/tupian.jpg')
rows,cols=img.shape[:2]   #读取原图像的长和宽
print(rows,cols)
#生成旋转矩阵M
pts1=np.float32([[150,50],[400,50],[60,450],[310,450]])
pts2=np.float32([[50,50],[rows-50,50],[50,cols-50],[rows-50,cols-50]])
M=cv2.getPerspectiveTransform(pts1,pts2)
#使用函数cv2.warpPerspective()进行透视变换
dst=cv2.warpPerspective(img,M,(cols,rows))
cv2.imshow('img',img)
cv2.imshow('dst',dst)
cv2.waitKey()
cv2.destroyAllWindows()

程序运行结果如下图所示,左为原图,右为透视变换的图。

我们可以看到,原图片经过透视映射后,变成另一个视角下的任意四边形了。

5 重映射

重映射是修改了像素点的位置,从而生成一幅新的图像,包括:复制、绕x轴y轴翻转,x轴y轴互换,图像缩放等。

均使用cv2.remap()重映射函数进行操作。

需要注意cv2.remap()中的两个参数mapx、mapy。mapx表示对应位置上x轴坐标值,mapy表示对应位置上y轴坐标值。

(一)复制

使用cv2.remap()函数完成图像复制,需先定义mapx,mapy的值,然后循环映射每个像素点到对应的位置上。

代码如下:

import cv2
import numpy as np
img=cv2.imread('E:/python_opencv/tupian.jpg')
rows,cols=img.shape[:2]         #读取行列数
mapx=np.zeros(img.shape[:2],np.float32) #mapx参数设定为对应位置上的x轴坐标值
mapy=np.zeros(img.shape[:2],np.float32) #mapy参数设定为对应位置上的y轴坐标值
for i in range(rows):          #对每个元素复制映射
  for j in range(cols):
    mapx.itemset((i,j),j)
    mapy.itemset((i,j),i)
rst=cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)
cv2.imshow('original',img)
cv2.imshow('result',rst)
cv2.waitKey()
cv2.destroyAllWindows()

执行后结果如下所示,可以看到,实现了图像的复制重映射。

(二)绕x轴翻转

重映射法对图像绕x轴翻转,表明mapx的值保持不变,mapy的值调整为总行数-1-当前行号,其余部分代码不变,所以循环体内代码变为:

 for i in range(rows):
   for j in range(cols):
     mapx.itemset((i,j),j)      #mapx的值保持不变
     mapy.itemset((i,j),rows-1-i)  #mapy的值调整为总行数-1-当前行号

(三)绕y轴翻转

重映射法对图像绕y轴翻转,表明mapx的值调整为总行数-1-当前列号,mapy的值保持不变,所以循环体内代码变为:

for i in range(rows):
  for j in range(cols):
     mapx.itemset((i,j),cols-1-j)  #mapx的值调整为总列数-1-当前列号
     mapy.itemset((i,j),i)      #mapy的值保持不变

(四)绕x轴y轴翻转

重映射也能实现图像绕x轴和y轴的同时翻转,只需将前两个部分合并,使mapx的值调整为总行数-1-当前列号,mapy的值调整为总行数-1-当前行号。例程如下:

import cv2
import numpy as np
img=cv2.imread('E:\python_opencv/tupian.jpg')
rows,cols=img.shape[:2]
mapx=np.zeros(img.shape[:2],np.float32)
mapy=np.zeros(img.shape[:2],np.float32)
for i in range(rows):
  for j in range(cols):
    mapx.itemset((i,j),cols-1-j)  #mapx的值调整为总列数-1-当前列号
    mapy.itemset((i,j),rows-1-i)  #mapy的值调整为总行数-1-当前行号
rst=cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)
cv2.imshow('original',img)
cv2.imshow('result',rst)
cv2.waitKey()
cv2.destroyAllWindows()

执行后结果如下所示,可以看到,实现了图像的绕x轴和y轴翻转重映射过程。

(五)x轴、y轴互换

重映射中,x轴、y轴互换表明,mapx的值变为所在行的行号,mapy的值变为所在列的列号。

但当行数和列数不一致时,行或列无法完成映射的部分就被处理为0。示例代码如下:

#使用函数cv2.remap()实现图像绕x轴和y轴的互换
import cv2
import numpy as np
img=cv2.imread('E:\python_opencv/tupian.jpg')
rows,cols=img.shape[:2]
mapx=np.zeros(img.shape[:2],np.float32)
mapy=np.zeros(img.shape[:2],np.float32)
for i in range(rows):
  for j in range(cols):
    mapx.itemset((i,j),i)  #mapx的值变为所在行的行号
    mapy.itemset((i,j),j)  #mapy的值变为所在列的列号
rst=cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)
cv2.imshow('original',img)
cv2.imshow('result',rst)
cv2.waitKey()
cv2.destroyAllWindows()

结果如图:

可以看到,列数多于行数的部分被置为0(黑色)。

(六)图像的缩放

重映射提供了cv2.remap()函数能够实现图像的放大或缩小。处理图像后,可以将图像固定在围绕其中心的某个区域。

下面例程中,x轴和y轴均缩小为原来的0.25-0.75倍之间。

import cv2
import numpy as np
img=cv2.imread('E:\python_opencv/tupian.jpg')
rows,cols=img.shape[:2]
mapx=np.zeros(img.shape[:2],np.float32)
mapy=np.zeros(img.shape[:2],np.float32)
for i in range(rows):
  for j in range(cols):
    if 0.25*cols < i < 0.75*cols and 0.25*rows < i < 0.75*rows:
      #在目标图像的x轴(0.25-0.75)倍之内生成缩小图像
      mapx.itemset((i,j),2*(j-0.25*cols)+0.5)
      #在目标图像的y轴(0.25-0.75)倍之内生成缩小图像
      mapy.itemset((i,j),2*(i-rows*0.25)+0.5)
    else:
      #不在上述区域的点都取(0,0)坐标点的值
      mapx.itemset((i,j),0)
      mapy.itemset((i,j),0)
rst=cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)  #图像缩放重映射
cv2.imshow('original',img)
cv2.imshow('result',rst)
cv2.waitKey()
cv2.destroyAllWindows()

到此这篇关于OpenCV+Python几何变换的实现示例的文章就介绍到这了,更多相关OpenCV 几何变换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • OpenCV图像几何变换之透视变换

    本文实例为大家分享了Android九宫格图片展示的具体代码,供大家参考,具体内容如下 1. 基本原理 透视变换(Perspective Transformation)的本质是将图像投影到一个新的视平面,其通用变换公式为: (u,v)为原始图像像素坐标,(x=x'/w',y=y'/w')为变换之后的图像像素坐标.透视变换矩阵图解如下: 仿射变换(Affine Transformation)可以理解为透视变换的特殊形式.透视变换的数学表达式为: 所以,给定透视变换对应的四对像素点坐标,即可求得透视变

  • Python3+OpenCV2实现图像的几何变换(平移、镜像、缩放、旋转、仿射)

    前言 总结一下最近看的关于opencv图像几何变换的一些笔记. 这是原图: 1.平移 import cv2 import numpy as np img = cv2.imread("image0.jpg", 1) imgInfo = img.shape height = imgInfo[0] width = imgInfo[1] mode = imgInfo[2] dst = np.zeros(imgInfo, np.uint8) for i in range( height ): f

  • OpenCV+Python几何变换的实现示例

    几何变换 图像的几何变换是指将一幅图像映射到另一幅图像内.有缩放.翻转.仿射变换.透视.重映射等操作. 1 缩放 使用cv2.resize()函数实现对图像的缩放,但要注意cv2.resize()函数内的dsize参数与原图像的行列属性是相反的,也就是:目标图像的行数是原始图像的列数,目标图像的列数是原始图像的行数. 下面举例说明cv2.resize()函数的用法: import cv2 img=cv2.imread('E:/python_opencv/tupian.jpg') rows,col

  • opencv python 2D直方图的示例代码

    Histograms - 3 : 2D Histograms 我们已经计算并绘制了一维直方图,因为我们只考虑一个特征,即像素的灰度强度值.但在二维直方图中,需要考虑两个特征,通常,它用于查找颜色直方图,其中两个要素是每个像素的色调和饱和度值. OpenCV中的2D直方图 使用函数cv.calcHist(), 对于颜色直方图,我们需要将图像从BGR转换为HSV. (请记住,对于1D直方图,我们从BGR转换为灰度).对于2D直方图,其参数将修改如下: channels = [0,1]:因为我们需要同

  • Opencv+Python 色彩通道拆分及合并的示例

    一.图像色彩通道拆分 import cv2 img1 = cv2.imread(r"D:\OpencvTest\example.jpg", cv2.IMREAD_COLOR) # 传入一张彩色图片 b, g, r = cv2.split(img1) cv2.imshow("exampleB", b) # 展示B通道图 cv2.imshow("exampleG", g) cv2.imshow("exampleR", r) B通道

  • Opencv python 图片生成视频的方法示例

    本文主要介绍了Opencv图片生成视频,分享给大家,具体如下: 生成视频 import random as rd import cv2 as cv import numpy as np # 保存视频 class RecordMovie(object): def __init__(self, img_width, img_height): self.video_writer = None # 视频对象 self.is_end = False # 结束保存视频 self.img_width = im

  • OpenCV+python实现膨胀和腐蚀的示例

    1,概念及原理: 膨胀(Dilating) (或) (1)将图像 A 与任意形状的内核 (B),通常为正方形或圆形,进行卷积. (2)内核 B 有一个可定义的 锚点, 通常定义为内核中心点. (3)进行膨胀操作时,将内核 B 划过图像A,将内核 B 覆盖区域的最大相素值提取,并代替锚点位置的相素.显然,这一最大化操作将会导致图像中的亮区开始"扩展" (因此有了术语膨胀 dilation ). 以3*3的内核为例: 腐蚀(Eroding) (与) (1)腐蚀在形态学操作家族里是膨胀操作的

  • python opencv肤色检测的实现示例

    1 椭圆肤色检测模型 原理:将RGB图像转换到YCRCB空间,肤色像素点会聚集到一个椭圆区域.先定义一个椭圆模型,然后将每个RGB像素点转换到YCRCB空间比对是否再椭圆区域,是的话判断为皮肤. YCRCB颜色空间 椭圆模型 代码 def ellipse_detect(image): """ :param image: 图片路径 :return: None """ img = cv2.imread(image,cv2.IMREAD_COLOR)

  • Python+Opencv实现数字识别的示例代码

    一.什么是数字识别?   所谓的数字识别,就是使用算法自动识别出图片中的数字.具体的效果如下图所示: 上图展示了算法的处理效果,算法能够自动的识别到LCD屏幕上面的数字,这在现实场景中具有很大的实际应用价值.下面我们将对它的实现细节进行详细解析. 二.如何实现数字识别?   对于数字识别这个任务而言,它并不是一个新的研究方向,很久之前就有很多的学者们在关注这个问题,并提出了一些可行的解决方案,本小节我们将对这些方案进行简单的总结. 方案一:使用现成的OCR技术. OCR,即文字识别,它是一个比较

  • python基于opencv批量生成验证码的示例

    基本思路是使用opencv来把随机生成的字符,和随机生成的线段,放到一个随机生成的图像中去. 虽然没有加复杂的形态学处理,但是目前看起来效果还不错 尝试生成1000张图片,但是最后只有998张,因为有有重复的,被覆盖掉了. 代码如下: import cv2 import numpy as np line_num = 10 pic_num = 1000 path = "./imgs/" def randcolor(): return (np.random.randint(0,255),n

  • Python OpenCV 图像平移的实现示例

    每次学习新东西的时候,橡皮擦都是去海量检索,然后找到适合自己理解的部分. 再将其拼凑成一个小的系统,争取对该内容有初步理解. 今天这 1 个小时,核心要学习的是图像的平移,在电脑上随便打开一张图片,实现移动都非常简单,但是在代码中,出现了一些新的概念. 检索 OpenCV 图像平移相关资料时,碰到的第一个新概念是就是 仿射变换. 每次看到这样子的数学名字,必然心中一凉,做为一个数学小白,又要瑟瑟发抖了. 百度一下,看看百科中是如何介绍的. 看过上图中的一些相关简介之后,对于这个概念也并没有太深刻

  • Python+OpenCV实现角度测量的示例代码

    本文介绍如何使用python语言实现角度测量,程序包括鼠标选点.直线斜率计算.角度计算三个子程序和一个主程序.最终实现效果:在图片上用鼠标确认三点,程序将会显示由此三点确定的角度,如下图所示. 1.鼠标选点 # -*- coding: utf-8 -*- import cv2 path = "picture_mqa\\angle_measure.bmp" img = cv2.imread(path) pointsList = [] def mousePoints(event,x,y,f

随机推荐