CV 两幅图像配准
http://www.cnblogs.com/Lemon-Li/p/3504717.html
图像配准算法一般可分为: 一、基于图像灰度统计特性配准算法;二、基于图像特征配准算法;三、基于图像理解的配准算法。
其中,算法类型二最普遍,基于特征的图像配准算法的核心步骤为:1.特征提取、2.特征匹配、3.模型参数估计、4.图像变换和灰度插值(重采样)。
图像配准必须得考虑3个问题: 分别是配准时所用到的空间变换模型、配准的相似性测度准则以及空间变换矩阵的寻优方式。
1)空间变换模型,是指的这两幅要配准的图像之间的映射模型,比如只有旋转、平移这些操作,那就是刚体变换模型,又比如有缩放操作,甚至X方向和Y方向缩放的幅度都还不一样,那就是仿射变换或者非线性变换模型。总之你要做配准,先要确定这两幅图像之间是一种什么样的映射模型。要是对这个变换模型还不清楚,你就到google上或者万方上搜索“仿射变换”、“刚体变换”这些关键词。帖子里不可能讲的太详细。
2)配准的相似性测度准则。在你确定了变换模型后,接下去要做什么?当然是确定模型里的参数了,而要确定这些参数(不同的变换模型参数个数是不一样的,像刚体变换有x平移、y平移和旋转角度sita三个参数,仿射变换有6个参数)你得告诉程序什么参数是最好的,或者说是正确的。那么判断什么参数是正确的一个准则就是我们说的配准的相似性测度准则,也就是告诉程序在某组参数下是配准的程度是多少,显然使得配准程度最好的那组参数就是我们要找的参数。3)空间变换矩阵的寻优方式。因为大多数情况下,模型中的参数不是靠解出来的,而是要靠“尝试-判断”这种方式去寻找,空间变换矩阵的寻优说白了也就是怎么对这些参数进行寻优,找出使得配准程度最好的那一组参数的过程。这里有很多方法,如遗传算法、粒子群优化算法等等,如果你对这些算法都不了解,没办法,你只有用最笨的遍历式搜索方法了,也就是以某一个步距,搜索所有的参数组合方式,然后找出使得按照相似性测度准则配准程度最高的那一组参数。
举例说明:比如有一幅图像A,我将A左移了2个像素,再往下移了3个像素,又顺时针旋转了60度,这时的图像我们称作B。如果我们要对A和B进行配准,其实就是确定2、3、60这三个参数的过程,因为这三个参数一旦确定了,我就知道了B和A的对应关系,换句话说对于B中的任何一个像素点我就知道在A中对应的是哪个点。这里因为我知道这两幅图只有平移和旋转的变换操作,所以我们采用的模型是刚体变换模型(实际情况下,你如果不知道这两幅图像进行了什么变换操作,只有大概根据图像的位置信息揣测了,一般情况下非线性变换模型是最正确的,但是参数也最多)。配准的相似性测度准则这里我们就用简单点的(只是举个例子说明下过程,事实上的许多情况都要复杂的多),以二值化后两幅图像重合的像素点个数为准,也就是说我们认为使得两幅图像重合的像素最多的那组参数就是正确的变换参数,理论上来讲,如果两幅图像严格配准了,那么显然他们所有的像素点都是重合的,否则就有错开的部分。寻优方法比较啰嗦,任何一个优化算法都不是几句话说的明白的,这里直接用遍历搜索法吧。因为有三个参数需要寻优因此,我们对这三个参数的解空间进行遍历,比如对X方向的平移像素个数我们从-100搜索到+100,步距为1像素,对Y方向的平移像素我们也从-100搜索到+100,步距为1像素,对旋转角度我们从0搜索到360度,步距为1度。这样等于说要完成一个200*200*360次的循环,然后在每次循环里面,我们都判断一下,按照当次循环参数进行变换后的A图像与B图像的重合像素个数有多少,找出200*200*360次循环中使得重合像素个数最多的那组循环中所使用的参数,这组参数就是我们所要的结果,如果一切正常,显然我们会在2,3,60这组参数所在循环中得到重合像素个数最多的结果。而所谓优化算法其实就是用一种更为智能的方式得到2,3,60这三个参数的过程。这样就完成了配准的过程。
多项式模型:在两幅图像上找到足够的同名点对,然后用多项式模型强行纠正。大小、旋转、噪声等都不是问题。
自己构造算法的话,可以这样。假设A为正确位置的图像,B是待校正的图像。B图上的任意一点(x,y),在校正后图像上的位置应该为(u,v)有(假设多项式为2阶):
u = a0 + a1*x + a2*y + a3*x2 + a4*y2 + a5*x*y
v = b0 + b1*x + b2*y + b3*x2 + b4*y2 + b5*x*y
在B图上散布取x,y值,在A图的同名点上取u,v值,当点数足够时,解a、b共12个参数。
得到方程后,遍历b图所有像元点x,y带入上述公式,就得到了全部配准后的位置u,v。
自动获取同名点比较困难些,其它容易。这个可以多阶,但如果像你说的非刚性变化一般3阶就够了。
两点线段匹配:选取两幅图的两个应该相同的点(一共4个点),得到4个点的坐标,然后用A图的两点线段与B图的两点线段计算出仿射变换的矩阵,再把矩阵应用于整幅图就行了。看看opencv吧,好多现成的API函数。
六参数配准(仿射变换)具体求法:一共是6个参数,坐标轴的变化夹角,旋转夹角,X尺度变化,Y尺度变化,X平移,Y平移。
进行一系列运算过后,可以变成一个线性代数式(具体怎么变换的不用管,比较复杂)
u = Ax + By + C
v = Dx + Ey + F
其中,U,V是目标图的横纵坐标,X,Y是原图横纵坐标.也就是说
[u v 1]'=[ A B C;D E F;0 0 1]*[x y z]'
具体A-F六个参数的计算可以通过SIFT在两张图中找到足够的尺度不变特征点,然后对这些特征点进行匹配。匹配后就能得到很多特征点对。然后建立
u = Ax + By + C
v = Dx + Ey + F
这样的方程。一共3对特征点,6个方程,就足够解6个参数了。但是实际上矩阵空间内三个远远不够。一般要把所有的一起拿来解超定方程组。
至于特征点匹配,SIFT应该能算出128位特征描述子,用两个点之间的特征描述子的欧式距离可以实现匹配。另外要速度优化的话可以不算这个,直接用灰度相关系数和一些其他算法来排除误匹配,比如ransac。其实128位特征描述子只有在进行初始配准的时候有用。而且128位空间的欧氏距离计算开销大,一般都用的正交反余弦来逼近。所以干脆不算这个东西,时间开销一下就少了70%以上。那么只知道一些特征点,用什么来进行初始匹配呢?方法就是用特征点之间的灰度相关系数,这个是很轻量级的。
总之,配准问题要实验,看结果,分析,再做改动,很难说有个算法能一定解决的。
需要考虑的可能问题包括:
resize分辨率,再做进一步处理的,控制特征点数量。
平滑去噪。
减少亮度对比度差异,用image normalization,就是先求图的mean,std,然后把所有pixel变换,使得最终mean是0,std是1.
surf算法、SIFT算子、Harris角点提取。
关于Image Alignment,推荐论文: Lucas-Kanade 20 years On: compositional algorithm,它是最慢的,不过根据我的经验来看,z在变换并不是特别大的时候,还蛮好用的。它适用于translation,scaling,rotation变换,寻找最优过程类似于用gradient of multi-variable function 寻找 local minimum。 但是假如变换太大,这个方法应该不行。关于代码,http://www.codeproject.com/KB/recipes/ImgAlign.aspx。 Remark:如果图像里有太多非刚性变换,忽略所有的推荐。
Shi-Tomasi角点特征+Lucas-kanade(光流).Harris's original definition involved taking the determinant of H(p), subtracting the trace of H(p) (with some weighting coefficient), and then comparing this difference to a predetermined threshold. It was later found by Shi and Tomasi [Shi94] that good corners resulted as long as the smaller of the two eigenvalues was greater than a minimum threshold. Shi and Tomasi's method was not only sufficient but in many cases gave more satisfactory results than Harris's method
CV 两幅图像配准的更多相关文章
- OpenCv实现两幅图像的拼接
直接贴上源码 来源:http://www.myexception.cn/image/1498389.html 实验效果 Left.jpg right.jpg ImageMatch.jpg #inclu ...
- 【OpenCV学习】计算两幅图像的重叠区域
问题描述:已知两幅图像Image1和Image2,计算出两幅图像的重叠区域,并在Image1和Image2标识出重叠区域. 算法思想: 若两幅图像存在重叠区域,则进行图像匹配后,会得到一张完整的全景图 ...
- Opencv实现两幅图像融合
实现两幅图像线性(不同系数下)的融合涉及到Opencv中两个关键的方法,addWeighted()和createTrackbar() addWeighted方法: 函数原型: void addWeig ...
- OpenCV,计算两幅图像的单应矩阵
平面射影变换是关于其次3维矢量的一种线性变换,可以使用一个非奇异的$3 \times 3$矩阵H表示,$X' = HX$,射影变换也叫做单应(Homography).计算出两幅图像之间的单应矩阵H,那 ...
- OpenCV 学习笔记(0)两幅图像标定配准
参考教程 依赖opencv扩展库,使用sifi匹配 保存配准信息 "./config/calibratedPara.yaml" #include <iostream> ...
- opencv::将两幅图像合并后,在同一个窗口显示;并将合并的图像流保存成视频文件
/** * @file main-opencv.cpp * @date July 2014 * @brief An exemplative main file for the use of ViBe ...
- OpenCV --- 实现两幅图像并排合并(ROI)
Mat img1 = imread("1.png"); Mat img2 = imread("2.png"); int height = img1.rows; ...
- OpenCV 对两幅图像求和(求混合(blending))
#include <cv.h> #include <highgui.h> #include <iostream> using namespace cv; int m ...
- Opencv探索之路(二十):制作一个简易手动图像配准工具
近日在做基于sift特征点的图像配准时遇到匹配失败的情况,失败的原因在于两幅图像分辨率相差有点大,而且这两幅图是不同时间段的同一场景的图片,所以基于sift点的匹配已经找不到匹配点了.然后老师叫我尝试 ...
随机推荐
- 学习C#基础知识这段时间
似乎穿越的感觉,我又来到了这周的周五,总是在周五,知道了时间的概念,上午会讲课,但是在下午就是一个总结小练习,上午老师给我们讲了委托,在听课时间感觉很简单啊,哪里有难的地方啊,一直在好奇,老师在演示给 ...
- c/c++左值和右值
C/C++中的变量有左值和右值之分,他们的区别主要如下: (1)左值可以放在赋值号 = 的左右两边,右值只能放在赋值号 = 的右边 (2)在C语言中,有名字的变量即为左值:而函数的运行结果或表达式中间 ...
- 如何理解精通PHP ?
「精通 PHP」可以理解为以下三个: 精通「PHP 解析器 精通「PHP 语法.函数(这门语言) 精通「PHP 项目开发 1 精通「PHP 解析器」 可以从这里开始学习: PHP核心:骇客指南 :ht ...
- Linux命令行常用光标移动快捷键
Linux 命令行快捷键 涉及在Linux命令行下进行快速移动光标.命令编辑.编辑后执行历史命令.Bang(!)命令.控制命令等.让basher更有效率. 常用 ctrl+左右键:在单词之间跳转 ct ...
- Shell 将两个文件按列合并
file1. 1 2 2 3 3 4 4 5 5 6 file2. a b b c c d d e e f 需要把file2的第二列合并到file1,使File1并成三列. 第一种方法:paste p ...
- JavaBean与Map<String,Object>相互转换
一.为什么要实现javaBean与Map<String,Object>相互转换 Spring中的BaseCommandController对象可以将传递过来的参数封装到一个JavaBean ...
- LeetCode——Integer to Roman
Description: Given an integer, convert it to a roman numeral. Input is guaranteed to be within the r ...
- 腾讯云大数据套件Hermes-MR索引插件使用总结
版权声明:本文由王亮原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/121 来源:腾云阁 https://www.qclou ...
- 如何在office2010中的EXCEL表格使用求和公式
EXCEL做表格非常方便,有时我们需要对表格中的很多数字进行求和计算,如果用计算器算会非常麻烦,别担心,用求和公式计算,非常简单的 工具/原料 电脑一台 offic2010软件一套 方法/步骤 ...
- POJ1125-Stockbroker Grapevine Floyd算法多源最短路径
这题的思路还是比较简单,用弗洛伊德算法打表后,枚举来找到最小值 代码如下 注意最后判断时候的语句 在这里错误了很多次 # include<iostream> # include<al ...