本例子为通过仿射扭曲变换将图像放置到另一幅图像中,使得它们能够和指定的区域或者标记物对齐。

运行的代码如下:

 # test.py
from PCV.geometry import warp, homography
from PIL import  Image
from pylab import *
from scipy import ndimage#放射扭曲im1到im2
#打开两张图片
im1 = array(Image.open('D:\pythonxy\image/wen.jpg').convert('L'))
im2 = array(Image.open('D:\pythonxy\image/yu.jpg').convert('L'))#设置映射的目标点
tp = array([[240,375,375,240],[143,145,275,275],[1,1,1,1]])#使用仿射变换将im1放置在im2上,使im1图像的角和tp尽可能的靠近
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)#选定im1角上的一些点
m,n = im1.shape[:2]
fp = array([[0,m,m,0],[0,0,n,n],[1,1,1,1]])# 第一个三角形
tp2 = tp[:,:3]
fp2 = fp[:,:3]# 计算仿射变换H,并且将其应用于图像im1
H = homography.Haffine_from_points(tp2,fp2)#affine仿射变换的方式把第一幅图像变到第二幅图像里面
im1_t = ndimage.affine_transform(im1,H[:2,:2],
(H[0,2],H[1,2]),im2.shape[:2])
# 对图像进行alpha通道处理,三角形的alphy
alpha = warp.alpha_for_triangle(tp2,im2.shape[0],im2.shape[1])
#创建alpha图像
im3 = (1-alpha)*im2 + alpha*im1_t
axis('off')
show()

运行的结果图如下:

图二建筑物来源于集美大学

其中主要用到了两个函数:warp 和 homography(单应)

warp函数中又用到了两个方法:image_in_image() 和 alpha_for_triangle()

  image_in_image() 方法的代码如下:

#tp是齐次表示的,并且是按照从左上角逆时针计算的
#使用仿射变换将im1放置在im2上,使im1图像的角和tp尽可能的靠近
def image_in_image(im1,im2,tp):# 扭曲的点m,n = im1.shape[:2]#点的坐标fp = array([[0,m,m,0],[0,0,n,n],[1,1,1,1]])#算出两个图像间的变换关系,返回给定对应点的最优仿射变换,并用H表示H = homography.Haffine_from_points(tp,fp)#affine通过仿射变换的方式把第一幅图像变到第二幅图像里面im1_t = ndimage.affine_transform(im1,H[:2,:2],(H[0,2],H[1,2]),im2.shape[:2])#alpha通道对图像进行处理alpha = (im1_t > 0)return (1-alpha)*im2 + alpha*im1_t

该方法的输入参数为两幅图像和一个tp坐标,该坐标为将第一幅图像放置到第二幅图像中的角点坐标,是齐次表示的。然后将扭曲的im1图像和im2图像融合,创建alpha图像。该alpha图像定义了每个像素从各个图像中获取的像素值成分的多少。扭曲的 图像是在扭曲区域边界以外用0来填充的图像,以此来创建一个二值的alpha图像。所以从严格意义上来说,我们需要在第一幅图像中的潜在0像素上加上一个小的数值。

  alpha_for_triangle() 方法的代码如下:

def alpha_for_triangle(points,m,n):#对于由角点定义的三角形创建大小为(m,n)的alpha映射(在归一化齐次坐标中给出)   alpha = zeros((m,n))for i in range(min(points[0]),max(points[0])):for j in range(min(points[1]),max(points[1])):x = linalg.solve(points,[i,j,1])#如果所有系数为正if min(x) > 0:alpha[i,j] = 1#返回alpha的值return alpha

alpha通道是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度信息,定义透明、不透明和半透明区域,其中白表示不透明,黑表示透明,灰表示半透明。使用alpha通道来给图像增加透明度。这里我们简单地为每个三角形创建了alpha图像,然后将所有的图像合并起来。该三角形的alpha图像可以简单地通过检查像素的坐标能否写成三角形顶点坐标的凸组合来计算得出。如果坐标可以表示成这种形式,那么该像素就位于三角形的内部。

homography函数中用到了Haffine_from_points()方法

Haffine_from_points()方法的代码如下:

def Haffine_from_points(fp,tp):
#对H进行仿射变换,tp是fp的仿射输注if fp.shape != tp.shape:raise RuntimeError('number of points do not match')#条件点m = mean(fp[:2], axis=1)maxstd = max(std(fp[:2], axis=1)) + 1e-9C1 = diag([1/maxstd, 1/maxstd, 1]) C1[0][2] = -m[0]/maxstdC1[1][2] = -m[1]/maxstdfp_cond = dot(C1,fp)# 条件点指向m = mean(tp[:2], axis=1)C2 = C1.copy() #must use same scaling for both point setsC2[0][2] = -m[0]/maxstdC2[1][2] = -m[1]/maxstdtp_cond = dot(C2,tp)# 条件点的平均值为零,所以平移为零A = concatenate((fp_cond[:2],tp_cond[:2]), axis=0)U,S,V = linalg.svd(A.T)# 创建B、C矩阵tmp = V[:2].TB = tmp[:2]C = tmp[2:4]tmp2 = concatenate((dot(C,linalg.pinv(B)),zeros((2,1))), axis=1) H = vstack((tmp2,[0,0,1]))# 仿射H = dot(linalg.inv(C2),dot(H,C1))return H / H[2,2]

该方法会返回给定对应点的最优仿射变换。以本例子来说,对应点为图像和黑方块的角点,如果透视效应比较弱,那么这种方法会返回很好的结果。

透视变换的本质是将图像投影到一个新的视平面。仿射变换可以理解为透视变换的特殊形式。

一幅图像就是一个像素坐标系下的各个带有像素值的坐标点,而透视变换可以理解为就是将一幅图像中的这些坐标点完成了一个坐标转换,将它们的坐标变换到了其他位置,从而实现了变换了图像视角的效果。因此,透视变换和相机标定等概念其实并没有什么内在关系。在车道线检测中的“相机标定”过程,其实就是做了一个透视变换,即相机画面图像和一幅假想的地面图像这两幅图像之间的变换关系,所谓假想的地面图像,即将实际地面上各点距离(离车辆后轴中心点)按一个设定的尺度放到一张图像上(鸟瞰图),此时只要是在这个地平面上的点,通过透视变换都可以得到其在相机图像上的点的坐标。因为假想的是在地平面上的点做的透视变换,所以此时只有位于地平面上的物体,才具有真正的鸟瞰图像素值,投影到图像上才是正常的。

计算机视觉学习(三):仿射变换将一幅图像放置到另一幅图像中相关推荐

  1. 使用仿射变换将一幅图像放置到另一幅图像中

    一,原理分析 仿射变换,又称仿射映射,是指在几何中,一个向量空间进行一次二维坐标到二维坐标的线性变换.仿射变换可以来表示:旋转 (线性变换),平移 (向量加),缩放操作 (线性变换),仿射变换代表的是 ...

  2. Java多线程学习三十:ThreadLocal 适合用在哪些实际生产的场景中

    我们在学习一个工具之前,首先应该知道这个工具的作用,能带来哪些好处,而不是一上来就闷头进入工具的 API.用法等,否则就算我们把某个工具的用法学会了,也不知道应该在什么场景下使用.所以,我们先来看看究 ...

  3. python计算机视觉学习第三章——图像到图像的映射

    目录 引言 一. 单应性变换 1.1 直接线性变换算法 1.2 仿射变换 二. 图像扭曲 2.1 图像中的图像 2.2 分段仿射扭曲 2.2 图像配准 三.创建全景图 3.1 RANSAC(随机一致性 ...

  4. Linux学习(三)

    Linux学习(三) vim编辑器与shell脚本 vim文本编辑器 在linux系统中一切都是文件,而配置一个服务就是在修改其配置文件的参数 vim编辑器中设置了三种模式 命令模式 末行模式 编辑模 ...

  5. OpenCV3 和 Qt5 计算机视觉 学习笔记 - 图像转换

    插件界面 void Transform_Plugin::setupUi(QWidget *parent) {ui = new Ui::PluginGui;ui->setupUi(parent); ...

  6. 【技术综述】图像与CNN发家简史,集齐深度学习三巨头

    文章首发于微信公众号<有三AI> [技术综述]图像与CNN发家简史,集齐深度学习三巨头 没有一个经典的发现会是突然之间横空出世,它总是需要一些积淀. 提起卷积神经网络,我们总会从LeNet ...

  7. 图像坐标:我想和世界坐标谈谈(A) 【计算机视觉学习笔记--双目视觉几何框架系列】

    玉米竭力用轻松具体的描述来讲述双目三维重建中的一些数学问题.希望这样的方式让大家以一个轻松的心态阅读玉米的<计算机视觉学习笔记>双目视觉数学架构系列博客.这个系列博客旨在捋顺一下已标定的双 ...

  8. 计算机视觉学习 BOW模型图像搜索

    BOW模型 bag of words 1.简介 bag of words是文档的一种建模方法,它可以把一个文档表示成向量数据,从而使计算机处理文档数据更加方便. 例如: 把文档中的单词抽取出来,可以构 ...

  9. OpenCV计算机视觉学习(1)——图像基本操作(图像视频读取,ROI区域截取,常用cv函数解释)

    人工智能学习离不开实践的验证,推荐大家可以多在FlyAI-AI竞赛服务平台多参加训练和竞赛,以此来提升自己的能力.FlyAI是为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台.每周免费提供 ...

最新文章

  1. Redis的文件格式
  2. oracle技术之检查点及SCN深入研究
  3. C语言数据类型本质分析
  4. 页面瘦身之压缩viewState和保存viewState到服务器
  5. 软RAID-mdadm折腾小记
  6. 怎样备份和恢复SAV企业版服务器的设置
  7. 使用diff和patch制作及打补丁
  8. ×××技术详解(二)
  9. Vue源码: 构造函数入口
  10. 发现本站一个非常简单易学的springClould教程 特此转载《方志朋》
  11. 《有限元分析及应用》第5章:变形体力学方程求解的试函数方法的原理
  12. 行测备考丨易混词傻傻分不清?大神来拯救你!
  13. 百度云盘MP3音乐外链、视频外链教程
  14. Unity制作3d生存游戏视频教程
  15. Stellarium0.19.3国内下载(64位)
  16. 贝壳找房二手房信息爬虫
  17. 分享三个前端学习方法和十项前端面试笔记:为想去的公司努力一把
  18. 明日方舟公式计算机,明日方舟公开招募公式汇总
  19. 音频codec调试心得
  20. Linux的发音问题

热门文章

  1. tp计算机术语是什么意思,tp是什么意思呀?谁能把术语给我解释一下? – 手机爱问...
  2. python调用usb设备_用Python与USB设备通信
  3. 五月飞花轻折柳 OpenStack黑客松在苏州等你
  4. html折叠新闻网页版本号,数字报纸HTML版本
  5. 一款彩票app的制作运营详解
  6. JDK 内置图形界面工具:海阔凭鱼跃,天高任鸟飞
  7. GD32汽车诊断协议 ISO-9141测试
  8. 大数据领域的Benchmark介绍
  9. 初识二维码 第二讲 二维码的结构
  10. PAT A1095 Cars on Campus ——一夜鱼龙舞