对图像块应用仿射变换,我们将其称为图像扭曲(或者仿射扭曲),其中一个简单的例子是:将图像或者图像的一部分放在另一幅图像中,使得它们能够和指定的区域或者标记物对齐。
1、仿射变换原理
仿射变换的原理就是进行空间的点坐标的变换,官方一点的解释是从二维坐标到二维坐标之间的线性变换,且保持二维图形的“平直性”和“平行性”。其参数公式为:
由于仿射变换具有6个自由度,所以需要三个对应点来估计矩阵H。其中X和Y为原坐标,X’和Y’为变换后的坐标,a~f为6个自由度,其中c、f参数分别为x方向和y方向的平移向量。
回到图像扭曲,就是把一个图像的角点映射在另一个图像的某个位置,将其覆盖的像素值替换,合成一幅图像。
2、α通道
阿尔法通道是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度信息,定义透明、不透明和半透明区域。如果一个像素的alpha通道数值为0,那它就是完全透明的(也就是看不见的),而数值为1则意味着一个完全不透明的像素(传统的数字图像)。我们常说的RGBA图像就是普通的RGB加上这个α通道。说白了就是控制图像透明度,在下面的代码段中:
tp = array([[120,260,260,120],[16,16,305,305],[1,1,1,1]])
的最后四个1就表示四个角点的透明度为不透明,以此实现图像的完全覆盖
3、代码示例
代码如下:
# -*- coding: utf-8 -*-
from PCV.geometry import warp, homography
from PIL import Image
from pylab import *
from scipy import ndimage
# example of affine warp of im1 onto im2
im1 = array(Image.open('校徽.jpg').convert('L'))
im2 = array(Image.open('尚大楼.jpg').convert('L'))
# set to points
tp = array([[420,830,830,420],[400,350,1060,1000],[1,1,1,1]])
#tp = array([[675,826,826,677],[55,52,281,277],[1,1,1,1]])
im3 = warp.image_in_image(im1,im2,tp)
figure()
gray()
subplot(141)
axis('off')
imshow(im1)
subplot(142)
axis('off')
imshow(im2)
subplot(143)
axis('off')
imshow(im3)
# set from points to corners of im1
m,n = im1.shape[:2]
fp = array([[0,m,m,0],[0,0,n,n],[1,1,1,1]])
# first triangle
tp2 = tp[:,:3]
fp2 = fp[:,:3]
# compute H
H = homography.Haffine_from_points(tp2,fp2)
im1_t = ndimage.affine_transform(im1,H[:2,:2],
(H[0,2],H[1,2]),im2.shape[:2])
# alpha for triangle
alpha = warp.alpha_for_triangle(tp2,im2.shape[0],im2.shape[1])
im3 = (1-alpha)*im2 + alpha*im1_t
# second triangle
tp2 = tp[:,[0,2,3]]
fp2 = fp[:,[0,2,3]]
# compute H
H = homography.Haffine_from_points(tp2,fp2)
im1_t = ndimage.affine_transform(im1,H[:2,:2],
(H[0,2],H[1,2]),im2.shape[:2])
# alpha for triangle
alpha = warp.alpha_for_triangle(tp2,im2.shape[0],im2.shape[1])
im4 = (1-alpha)*im3 + alpha*im1_t
subplot(144)
imshow(im4)
axis('off')
show()
结果如下:
结果分析:图一为集美大学校徽的灰度图像,图二为集美大学尚大楼的灰度图像,通过修改tp = array([[420,830,830,420],[400,350,1060,1000],[1,1,1,1]])
这一行的坐标点可以改变图一映射在图二的位置,其中前四个数字代表四个角点的纵坐标,中间四个数字代表四个角点的横坐标,四个角点的顺序为从左上角开始按照逆时针方向排序,最后四个数字代表四个角点的α通道。图三和图四都是图片的重合,但是图三是图一和图二的重合,而图四是图三和图一的重合,所以根据我细心地找点(不知道有没有可以精确定位的方法,所以我的坐标都是图上慢慢找的)想要达到的效果应该是图四这样让图一成为一个梯形映射在图二之上相对比较美观。
4、调整warp.py文件
打开 PCV-master\PCV\geometry 目录下的warp.py文件,将第一行的代码后半段删除,只留下import matplotlib
,以及第113行和128行的print后面加上括号,代码示例才不会报错。