仿射扭曲之图像中的图像

该博客介绍了一个简单的仿射扭曲应用,通过计算单应性矩阵将一张图像或其部分放置到另一图像的特定位置。讨论了homograph.Haffine_from_points()函数的原理,解释了仿射变换如何保持平直性和平行性但不保留原始尺寸和角度。还解决了在运行代码时遇到的matplotlib.delaunay模块缺失的问题,并提供了解决方案。
摘要由CSDN通过智能技术生成

实现仿射扭曲中一个简单的例子,将图像或者图像中的一部分放置在另一幅图像指定的位置中

运行代码及结果

具体代码如下:

from PCV.geometry import warp,homography
from PIL import Image
from pylab import *
from scipy import ndimage

im1=array(Image.open('D:/输入图片/aa_12.jpg').convert('L'))
im2=array(Image.open('D:/输入图片/aa_16.jpg').convert('L'))

tp=array([[7,7,402,402],[4,157,157,4],[1,1,1,1]])
im3=warp.image_in_image(im1,im2,tp)

figure()
gray()
imshow(im3)
axis('equal')
axis('off')
show()
imshow(im2)
axis('equal')
axis('off')
show()

输入的两张图片如下:
图一:
在这里插入图片描述
图二:
在这里插入图片描述

运行结果如下:
在这里插入图片描述
在这里插入图片描述

此代码中fp是图一四个边角的坐标,这里我获取的是图一整张图片,tp是图二中目标位置四个边角的坐标,在我的代码中y位置在前面,x位置在后面,即[左上角的y坐标,右上角的y坐标,右下角的y坐标,左下角的y坐标],[左上角的x坐标,右上角的x坐标,右下角的x坐标,左下角的x坐标]。目标位置的选定输入一定要正确,否则在目标位置贴上的图片既怪异又丑陋…

函数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. """ 
        
       m,n = im1.shape[:2]
       fp = array([[0,0,n,n],[0,m,m,0],[1,1,1,1]])
       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
   

homograph.Haffine_from_points(tp,fp)负责算出这四个点对的变换关系。homograph的意思是单应性矩阵,它的适用场景为:当场景中的特征点都落在同一平面上,比如墙、地面等,此时可用单应性估计运动。其描述方程为
在这里插入图片描述
H乘以一个不为0的数
在这里插入图片描述
H是一个3*3的矩阵。假设已经获得了两幅图像之间的单应矩阵,可得
在这里插入图片描述
其中左边为图像1中的点,右边为图像2中的点。

affine_transform的意思是仿射变换,是一种二维坐标到二维坐标之间的线性变换,保持二维图形的“平直性”和“平行性”,其实是指保二维图形间的相对位置关系不变,平行线还是平行线,相交直线的交角不变,但是仿射变换不能保持原来的线段的长度不变,也不能保持原来的夹角角度不变。下图是变换过程的运算:
在这里插入图片描述
c,f是平移量,a,b,d,e反映了图像旋转、缩放等变化,将这些参数计算出来,就可以得到两幅图像的坐标变换关系。
这样图一所要截取的区域经过仿射变换映射到图二的目标位置上,且大小和图二的目标区域一样。

alpha通道方法则是设置图二的目标区域部分值为1,其他区域值为0,(0是背景为黑色,1是前景为白色),先映射出一张和图二一样的图像a(相当于先建立一个蒙板),然后在蒙板里把不需要的地方填充成黑色,需要的地方即目标区域留成白色,这个时候实际上是做了一次乘法。用黑色所代表的数值0去乘以图二 ,那么这个地方就变透明了,用白色所代表的数值乘以目标区域,再将两者相加,这样图一就能贴在图二的目标区域上。

调试代码中遇到的问题

No module named ‘matplotlib.delaunay’
如果你们也遇到了这种问题,说明matplotlib库中已经不再支持delaunay模块了,需要去warp.py文件中修改两部分,如下
在这里插入图片描述
在这里插入图片描述这样就ok啦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值