图像的仿射变换是二维坐标到二维坐标的线性变换,而且保留了原图像的“平直性”(意为在二维的坐标中图像的直线经过仿射变换还是直线。)和“平行性”(意为图像经过仿射变换,其直线的关系不会改变,即平行线依旧还是平行线),但是仿射变换可以改变原图像的角度,使其仿射之后变得倾斜。其公式如下
化简
这次实验就是使用了仿射变换在图像的使用。使原图像通过仿射变换放置到目标图像中。因为在Python中关于仿射变换的具体代码已经集合封装到warp.py
和homography.py
中。我们只需要导入直接使用里面的函数,就可以跑出结果。
我们实现图像到图像仿射变换的主要的函数是image_in_image
,其具体实现代码如下:
def image_in_image(im1,im2,tp):
""" Put im1 in im2 with an affine transformation
such that corners are as close to tp as possible.
tp are homogeneous and counter-clockwise from top left. """
# points to warp from
m,n = im1.shape[:2]
fp = array([[0,m,m,0],[0,0,n,n],[1,1,1,1]])
# compute affine transform and apply
H = homography.Haffine_from_points(tp,fp)
im1_t = ndimage.affine_transform(im1,H[:2,:2],
(H[0,2],H[1,2]),im2.shape[:2])
alpha = (im1_t > 0)
return (1-alpha)*im2 + alpha*im1_t
函数传递的参数为两幅我们需要进行图像放置的的图像,以及一个存放在目标图像中放置位置的坐标。需要注意的是,坐标点是以逆时针的顺序从左上角开始。函数中im1_t
是原图像通过仿射变换得到的新图像。alpha = (im1_t > 0)
是将仿射变换后的图像转换为二值得alpha图像。通过
(1-alpha)*im2 + alpha*im1_t
来将二值alpha图像和目标图像做简单的计算,从而使原图像能够完好的放置在目标图像中。
放置的具体实现代码如下:
# -*- 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('E:/Py_code/photo/westb.jpg').convert('L'))
im2 = array(Image.open('E:/Py_code/photo/(2).jpg').convert('L'))
# set to points
tp = array([[1250,1900,1900,1250],[560,560,930,930],[1,1,1,1]])
im3 = warp.image_in_image(im1,im2,tp)
figure()
gray()
subplot(131)
axis('off')
imshow(im1)
subplot(132)
axis('off')
imshow(im2)
subplot(133)
axis('off')
imshow(im3)
show()
实验结果:
需要注意的是,要想将原图像能在目标图像有很好的放置效果,需要在
tp = array([[1250,1900,1900,1250],[560,560,930,930],[1,1,1,1]])
中修改在目标图像放置的坐标。前文提到坐标是逆时针顺序从左上角开始,故第一个数组的值分别是从左上角开始以逆时针顺序到右上角的y轴的值,同理第二个为x轴的值。第三个是设置一个alpha通道并赋值为1,使我们原图像前景能显示出来(0为背景,相当于是全透明)。
实验的目标图像是集美大学最高也是最大气的建筑——尚大楼了。作为威少的粉丝,这几场威少的表现不尽人意,作为球迷,我觉得很是心痛,于是恶趣味了一把,从我一个威黑朋友中拿了这张图。
因为我所学习的教材中,python是2.7的版本,本人装的是3.7的版本,于是在包的导入时候遇到问题,因为是版本的问题,百度很多也没有解决办法,这里感谢同级的软件专业同学吴则彪。通过他提供的解决办法,解决了版本的问题。以下是错误和吴则彪同学的解决方法:
这是我当时因为版本问题导致的导入错误。只需要将from scipy.spatial import Delaunay
替换掉warp.py
中的第一句导入,问题就解决了。
如果您在阅读之中发现文章错误之处或者出现疑问,欢迎在评论指出。