首页 > 技术知识 > 正文

一、学习目标

了解图片如何进行仿射变换 了解图片如何进行图片融合

上一篇:[python opencv 计算机视觉零基础到实战]二十、镜像、腐蚀、膨胀、开运算、闭运算

二、了解图片的仿射变换与融合添加水印

2.1 了解如何对图片进行仿射变换

在opencv中,我们可以对图片图片进行仿射变换。那仿射变换到底是啥?仿射变换其实就是线性变换加上平移;那什么是线性变换呢?我们可以简单的理解线性变换就是缩放加上旋转。理解了之后我们就知道我们这个仿射变换能够做什么了。

首先,我们需要获取图片,老代码如下:

img = cv2.imread(rC:\Users\mx\Desktop\1.jpg) cv2.namedWindow(“Image”,cv2.WINDOW_NORMAL)

在仿射变换中需要用到原图的宽高,所以我们需要获取,代码如下:

imgInfo=img.shape height=imgInfo[0] width=imgInfo[1]

之后我们需要记录一下原图的3个点,这3个点用来确定整个平面:

pointSrc=np.float32([[0,0],[0,height-1],[width-1,0]])

以上代码中[0,0]是初始点,[0,height-1]原点上的最高点,[width-1,0]为原点上的最宽点。这样就确定了这个图片平面。之后我们还需要一个变换后的点。代码如下:

pointDst=np.float32([[30,30],[130,height-100],[width-100,130]])

以上代码是表示pointSrc的原图的3个点,将要出现在哪些位置,例如以上代码的[30,30]表示[0,0]变换到此处;[130,height-100]表示[0,height-1]变换到此处;[width-100,130]表示[width-1,0]变换到此处。

2.2 了解getAffineTransform方法组合矩阵

接下来需要组合以上的两个矩阵,需要使用getAffineTransform方法对初始点与映射后的点进行组合。代码如下: af=cv2.getAffineTransform(pointSrc,pointDst)

以上代码中getAffineTransform方法内第一个为原始点,第二个为映射点。组合完毕后使用仿射变换方法warpAffine。代码如下:

afimg=cv2.warpAffine(img,af,(width,height))

warpAffine方法中,第一个参数是需要放射变换的图片,第二个参数为仿射变换的矩阵,也就上上面通过getAffineTransform方法组合后的矩阵,组后一个参数是原图的宽高。所有完整代码如下:

import cv2 import numpy as np img = cv2.imread(rC:\Users\mx\Desktop\1.jpg) cv2.namedWindow(“Image”,cv2.WINDOW_NORMAL) imgInfo=img.shape height=imgInfo[0] width=imgInfo[1] pointSrc=np.float32([[0,0],[0,height-1],[width-1,0]]) pointDst=np.float32([[30,30],[130,height-100],[width-100,130]]) af=cv2.getAffineTransform(pointSrc,pointDst) afimg=cv2.warpAffine(img,af,(width,height)) cv2.imshow(“afimg”, afimg) cv2.imshow(“Image”, img) cv2.waitKey (0) cv2.destroyAllWindows()

随后我们运行程序查看效果:

[python opencv 计算机视觉零基础到实战]二十一、仿射变换与图片融合

我们也可以调整一下pointDst映射后的图片位置信息,从而验证我所说的是否正确。例如我将[30,30]改为100,100,此时肯定会图片往下移动,我们更改如下:

pointDst=np.float32([[100,100],[130,height-100],[width-100,130]])

[python opencv 计算机视觉零基础到实战]二十一、仿射变换与图片融合1

从结果中验证了该数据的正确性。

2.3 了解使用addWeighted方法为图片添加水印

为图片添加水印其实就是融合两张图片,每张图片所占的权重不一样,那么现实的结果也不一样。这时权重大的越清晰,权证越小的则会越透明。首先我们引入两张图片与一张图的宽高,代码如下:

img1 = cv2.imread(rC:\Users\mx\Desktop\1.jpg) img2 = cv2.imread(rC:\Users\mx\Desktop\2.jpg) cv2.namedWindow(“Image”,cv2.WINDOW_NORMAL) imgInfo=img1.shape height=imgInfo[0] width=imgInfo[1]

图片融合需要图片有相同的大小,我们在此处了方便,那么我们就随意的使用图片进行取区域进行图片融合。例如我们想取图片的一半大小只需要对图片的宽高缩小一半即可:

roiH=int(height/2) roiW=int(width/2)

这个时候只需要对图片矩阵进行取值,这个时候就可以得到大小完全一样的矩阵内容了,前提是,你的两张图片大小不能差距太大,不然取一半的话另外一张图片不一定有足够大的宽高,我们这时候可以将一半的值改为三分之一或者四分之一都行。代码如下:

img1ROI=img1[0:roiH,0:roiW] img2ROI=img2[0:roiH,0:roiW]

接下来就需要使用addWeighted方法了。addWeighte第一个参数是图片1,第二个参数是图片1的权重,第三个参数是图片2,第四个参数是图片2的权重。第五个参数为两个图相加后再相加的值。代码如下:

dst=cv2.addWeighted(img1ROI,0.8,img2ROI,0.2,0)

以上代码中img1ROI为图1,img2ROI为图2,第一张图我给的权重是0.8,第二张图我给的权重是0.2。从权重上就可以看出,我主要是显示第一张图,第二张图将会半虚化透明的方式呈现。完整代码如下:

import cv2 import numpy as np img1 = cv2.imread(rC:\Users\mx\Desktop\1.jpg) img2 = cv2.imread(rC:\Users\mx\Desktop\2.jpg) cv2.namedWindow(“Image”,cv2.WINDOW_NORMAL) imgInfo=img1.shape height=imgInfo[0] width=imgInfo[1] roiH=int(height/2) roiW=int(width/2) img1ROI=img1[0:roiH,0:roiW] img2ROI=img2[0:roiH,0:roiW] dst=cv2.addWeighted(img1ROI,0.8,img2ROI,0.2,0) cv2.imshow(“Image”, dst) cv2.waitKey (0) cv2.destroyAllWindows()

结果如下:

[python opencv 计算机视觉零基础到实战]二十一、仿射变换与图片融合2

第一张图为主图,呈现的很清楚,第二张图为虚影。这时我们也可以将添加虚影的部分还原到原图之中,代码如下:

dst=cv2.addWeighted(img1ROI,0.8,img2ROI,0.2,0) img1[0:roiH,0:roiW]=dst

结果如下:

[python opencv 计算机视觉零基础到实战]二十一、仿射变换与图片融合3

想要调整第二张图的显现可以增加权重,代码如下:

dst=cv2.addWeighted(img1ROI,0.8,img2ROI,0.5,0)

结果如下:

[python opencv 计算机视觉零基础到实战]二十一、仿射变换与图片融合4

三、总结

了解图片使用warpAffine进行仿射变换 了解图片使用addWeighted进行图片融合

猜你喜欢