计算机视觉学习六:图像仿射
一、实验:利用图像仿射将一张图像放置到另一张图像中
注:本实验所采用图像仍旧是集美大学图片
# -*- 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('../images/9.jpg').convert('L'))
im2 = array(Image.open('../images/ch3.jpg').convert('L'))
# set to points目标坐标
tp = array([[280,680,680,280],[400,400,705,705],[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(131)
axis('off')
imshow(im1)
subplot(132)
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(133)
imshow(im4)
axis('off')
show()
运行使用狄洛克三角剖分方法时提示错误
ModuleNotFoundError: No module named ‘matplotlib.delaunay’
解决方法参考博客:https://blog.csdn.net/qq_33363973/article/details/80181950
二、原理分析
1、仿射原理
仿射变换能够保持图像的“平直性”,包括旋转,缩放,平移,错切操作。一般而言,仿射变换矩阵为23的矩阵,第三列的元素起着平移的作用,前面两列的数字对角线上是缩放,其余为旋转或者错切的作用。
仿射变换是一种二维坐标(x, y)到二维坐标(u, v)的线性变换,其数学表达式形式如下:
对应的齐次坐标矩阵表示形式为:
仿射变换保持了二维图形的“平直性”(直线经仿射变换后依然为直线)和“平行性”(直线之间的相对位置关系保持不变,平行线经仿射变换后依然为平行线,且直线上点的位置顺序不会发生变化)。非共线的三对对应点确定一个唯一的仿射变换。
其计算方法为坐标向量和变换矩阵的乘积,换言之就是矩阵运算。在应用层面,放射变换是图像基于3个固定顶点的变换,如图1.1所示:
图中红点即为固定顶点,在变换先后固定顶点的像素值不变,图像整体则根据变换规则进行变换同理,透视变换是图像基于4个固定顶点的变换,如图1.2所示:
参考博客:https://www.imooc.com/article/27535
2、alpha通道
alpha通道是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度信息,定义透明、不透明和半透明区域,其中白表示不透明,黑表示透明,灰表示半透明。
根据Alpha通道数据进行图像混合的算法:
把需要组合的颜色计算出不含Alpha分量的原始RGB分量然后相加便可。如:两幅图像分别为A和B,由这两幅图像组合而成的图像称为C,则可用如下四元组表示图A和B,三元组表示图像C:
A:(Ra,Ga,Ba,Alphaa)
B:(Rb,Gb,Bb,Alphab)
C:(Rc,Gc,Bc)
根据上述算法,则:
Rc=RaAlphaa+RbAlphab
Gc=GaAlphaa+GbAlphab
Bc=BaAlphaa+Bb*Alphab
这就是两图像混合后的三原色分量。如果有多幅图像需要混合,则按照以上方法两幅两幅地进行混合。
参考博客:https://www.cnblogs.com/suogasus/p/5311264.html
3、单应性变换(homography)
单应性变换是将一个平面内的点映射到另一个平面内的二维投影变换。在这里,平面是指图像或者三维中的平面表面。单应性变换具有较强的实用性,比如图像配准,图像纠正和纹理扭曲,以及创建全景图像。本质上,单应性变换H,按照下面的方程映射:
一幅2D图像上的非齐次坐标为(x,y),而齐次坐标为(x,y,1),也可以写成(x/z,y/z,1)或(x,y,z)。点的齐次坐标依赖于其尺度定义的,因此,单应性矩阵H也仅依赖尺度定义,所以,单应性矩阵具有8个独立的*度。通常用w=1来归一化点。
下面对本次实验中的homegraphy.py文件进行注解:
-
def normalize(points)
在齐次坐标意义下,对点集进行归一化,使最后一行为1 -
def make_homog(points)
将点集转换为齐次坐标显示 -
def H_from_points(fp,tp)
使用线性DLT方法,计算单应性矩阵H,使fp(对应点矩阵)映射到tp。点自动进行归一化。 -
Haffine_from_points(fp,tp)
计算单应性矩阵H,仿射变换,使得tp是fp经过仿射变换H得到的,返回给定对应点的最优仿射变换。
单应性变换推导参考博客:http://www.cnblogs.com/ml-cv/p/5871052.html
4、wrap.py文件注解: -
def image_in_image(im1,im2,tp)
输入参数为两幅图像和一个坐标,该坐标为将第一幅图像放置到第二幅图像中的角点坐标。利用该函数将第一幅图像插入到第二幅图像中。