RANSAC算法实现去除误匹配并计算拼接矩阵-随笔

2023-05-16

1.RANSAC算法实现去除误匹配并计算拼接矩阵流程

(1) 从样本集中随机抽选一个RANSAC样本,即4个匹配点对(至少4个匹配点对,才能计算出3*3变换矩阵);

(2) 计算当错误概率为0.1(即90%正确率)的情况下所需最少匹配点对数,赋值给in_min;

(3) 计算初始的错误概率p = pow( 1.0 - pow( in_frac, m ), k )(初始状态k=0,m为随机抽样匹配点对数通常为4);

(4) srand( time(NULL) );//初始化随机数生成器

(5) while(p > p_badxform )循环执行迭代,终止条件是实际计算错误概率小于预设p_badxform 错误概率,通常p_badxform =0.01(即99%正确率);

(5-1) 分别计算当前点和匹配点的坐标(x,y)分别存入pts和mpts的Point类型点集中;

(5-2) 利用传入的lsq_homog函数根据pts、mpts和m来计算根据随机选取的四个匹配对所得变换矩阵;

(5-2-1) lsq_homog函数通过调用OpenCv的cvSolve函数来计算pts到mpts的变换矩阵,cvSolve详解请参考http://blog.csdn.net/u011028345/article/details/78402625

(5-3) 若能成功计算出变换矩阵,执行(5-4),若不能成功计算出变换矩阵,更新当前错误概率p(因为即使没有计算出变换矩阵,但迭代k值增加了,依旧要重新计算错误概率),执行(5-1),继续迭代随机选择4对匹配点;

(5-4) 给定特征点集,变换矩阵,误差函数,计算出当前一致集consensus,返回一致集中元素个数给in;

(5-5) 若当前一致集大于历史最优一致集,即当前一致集为最优,则更新最优一致集consensus_max;

(5-6) 更新当前错误概率p;

 重复执行(5)迭代,直到条件终止。

(6) 若最优一致集中元素个数大于最低标准,即符合要求,根据最优一致集中所有符合要求的匹配点对,利用lsq_homog函数中的cvSolve的最小二乘法求得变换矩阵。


RANSAC算法的迭代终止条件是当前错误概率p小于允许的最小错误概率p_badxform,一般传入的值为0.01,即要求正确率达到99%

当前错误概率p的计算公式为:p=( 1 - in_fracm)k

其中in_frac是当前最优一致集中元素(内点)个数占样本总数的百分比,表征了当前最优一致集的优劣;

m是计算变换矩阵需要的最小特征点对个数,是固定值,一般是4;k是迭代次数。

所以,内点所占比例in_frac越大,错误概率越小;迭代次数k越大,错误概率越小,用来保证收敛。


2.RobHess的RANSAC源码分析

/*利用RANSAC算法进行特征点筛选,计算出最佳匹配的变换矩阵 
参数: 
features:特征点数组,只有当mtype类型的匹配点存在时才被用来进行单应性计算 
n:特征点个数 
mtype:决定使用每个特征点的哪个匹配域进行变换矩阵的计算,应该是FEATURE_MDL_MATCH, 
    FEATURE_BCK_MATCH,FEATURE_MDL_MATCH中的一个。若是FEATURE_MDL_MATCH, 
    对应的匹配点对坐标是每个特征点的img_pt域和其匹配点的mdl_pt域, 
    否则,对应的匹配点对是每个特征点的img_pt域和其匹配点的img_pt域。 
xform_fn:函数指针,指向根据输入的点对进行变换矩阵计算的函数,一般传入lsq_homog()函数 
m:在函数xform_fn中计算变换矩阵需要的最小特征点对个数 
p_badxform:允许的错误概率,即允许RANSAC算法计算出的变换矩阵错误的概率,当前计算出的模型的错误概率小于p_badxform时迭代停止 
err_fn:函数指针,对于给定的变换矩阵,计算推定的匹配点对之间的变换误差,一般传入homog_xfer_err()函数 
err_tol:容错度,对于给定的变换矩阵,在此范围内的点对被认为是内点 
inliers:输出参数,指针数组,指向计算出的最终的内点集合,若为空,表示没计算出符合要求的一致集 
        此数组的内存将在本函数中被分配,使用完后必须在调用出释放:free(*inliers) 
n_in:输出参数,最终计算出的内点的数目 
返回值:RANSAC算法计算出的变换矩阵,若为空,表示出错或无法计算出可接受矩阵 
*/  

CvMat* ransac_xform( struct feature* features, int n, int mtype,  
                    ransac_xform_fn xform_fn, int m, double p_badxform,  
                    ransac_err_fn err_fn, double err_tol,  
                    struct feature*** inliers, int* n_in )  
{  
    //matched:所有具有mtype类型匹配点的特征点的数组,也就是样本集  
    //sample:单个样本,即4个特征点的数组  
    //consensus:当前一致集;  
    //consensus_max:当前最大一致集(即当前的最好结果的一致集)  
    struct feature** matched, ** sample, ** consensus, ** consensus_max = NULL;  
    struct ransac_data* rdata;//每个特征点的feature_data域的ransac数据指针  
    CvPoint2D64f* pts, * mpts;//每个样本对应的两个坐标数组:特征点坐标数组pts和匹配点坐标数组mpts  
    CvMat* M = NULL;//当前变换矩阵  
    //p:当前计算出的模型的错误概率,当p小于p_badxform时迭代停止  
    //in_frac:内点数目占样本总数目的百分比  
    double p, in_frac = RANSAC_INLIER_FRAC_EST;  
    //nm:输入的特征点数组中具有mtype类型匹配点的特征点个数  
    //in:当前一致集中元素个数  
    //in_min:一致集中元素个数允许的最小值,保证RANSAC最终计算出的转换矩阵错误的概率大于0.1小于p_badxform所需的最小内点数目  
    //in_max:当前最优一致集(最大一致集)中元素的个数  
    //k:迭代次数,与计算当前模型的错误概率有关  
    int i, nm, in, in_min, in_max = 0, k = 0;  
  
    //找到特征点数组features中所有具有mtype类型匹配点的特征点,放到matched数组(样本集)中,返回值nm是matched数组的元素个数  
    nm = get_matched_features( features, n, mtype, &matched );  
    //若找到的具有匹配点的特征点个数小于计算变换矩阵需要的最小特征点对个数,出错  
    if( nm < m )  
    {   //出错处理,特征点对个数不足  
        fprintf( stderr, "Warning: not enough matches to compute xform, %s" \  
            " line %d\n", __FILE__, __LINE__ );  
        goto end;  
    }  
  
    /* initialize random number generator */  
    srand( time(NULL) );//初始化随机数生成器  
  
    //计算保证RANSAC最终计算出的转换矩阵错误的概率小于p_badxform所需的最小内点数目  
    in_min = calc_min_inliers( nm, m, RANSAC_PROB_BAD_SUPP, p_badxform );  
    //当前计算出的模型的错误概率,内点所占比例in_frac越大,错误概率越小;迭代次数k越大,错误概率越小  
    p = pow( 1.0 - pow( in_frac, m ), k );  
    i = 0;  
  
    //当前错误概率大于输入的允许错误概率p_badxform,继续迭代  
    while( p > p_badxform )  
    {  
        //从样本集matched中随机抽选一个RANSAC样本(即一个4个特征点的数组),放到样本变量sample中  
        sample = draw_ransac_sample( matched, nm, m );  
        //从样本中获取特征点和其对应匹配点的二维坐标,分别放到输出参数pts和mpts中  
        extract_corresp_pts( sample, m, mtype, &pts, &mpts );  
        //调用参数中传入的函数xform_fn,计算将m个点的数组pts变换为mpts的矩阵,返回变换矩阵给M  
        M = xform_fn( pts, mpts, m );//一般传入lsq_homog()函数  
        if( ! M )//出错判断  
            goto iteration_end;  
        //给定特征点集,变换矩阵,误差函数,计算出当前一致集consensus,返回一致集中元素个数给in  
        in = find_consensus( matched, nm, mtype, M, err_fn, err_tol, &consensus);  
  
        //若当前一致集大于历史最优一致集,即当前一致集为最优,则更新最优一致集consensus_max  
        if( in > in_max )  
        {  
            if( consensus_max )//若之前有最优值,释放其空间  
                free( consensus_max );  
            consensus_max = consensus;//更新最优一致集  
            in_max = in;//更新最优一致集中元素个数  
            in_frac = (double)in_max / nm;//最优一致集中元素个数占样本总个数的百分比  
        }  
        else//若当前一致集小于历史最优一致集,释放当前一致集  
            free( consensus );  
        cvReleaseMat( &M );  
  
iteration_end:  
        release_mem( pts, mpts, sample );  
        p = pow( 1.0 - pow( in_frac, m ), ++k );//更新当前错误概率  
    }  
  
    //根据最优一致集计算最终的变换矩阵  
    /* calculate final transform based on best consensus set */  
    //若最优一致集中元素个数大于最低标准,即符合要求  
    if( in_max >= in_min )  
    {  
        //从最优一致集中获取特征点和其对应匹配点的二维坐标,分别放到输出参数pts和mpts中  
        extract_corresp_pts( consensus_max, in_max, mtype, &pts, &mpts );  
        //调用参数中传入的函数xform_fn,计算将in_max个点的数组pts变换为mpts的矩阵,返回变换矩阵给M  
        M = xform_fn( pts, mpts, in_max );  
        /***********下面会再进行一次迭代**********/  
        //根据变换矩阵M从样本集matched中计算出一致集consensus,返回一致集中元素个数给in  
        in = find_consensus( matched, nm, mtype, M, err_fn, err_tol, &consensus);  
        cvReleaseMat( &M );  
        release_mem( pts, mpts, consensus_max );  
        //从一致集中获取特征点和其对应匹配点的二维坐标,分别放到输出参数pts和mpts中  
        extract_corresp_pts( consensus, in, mtype, &pts, &mpts );  
        //调用参数中传入的函数xform_fn,计算将in个点的数组pts变换为mpts的矩阵,返回变换矩阵给M  
        M = xform_fn( pts, mpts, in );  
        if( inliers )  
        {  
            *inliers = consensus;//将最优一致集赋值给输出参数:inliers,即内点集合  
            consensus = NULL;  
        }  
        if( n_in )  
            *n_in = in;//将最优一致集中元素个数赋值给输出参数:n_in,即内点个数  
        release_mem( pts, mpts, consensus );  
    }  
    else if( consensus_max )  
    {   //没有计算出符合要求的一致集  
        if( inliers )  
            *inliers = NULL;  
        if( n_in )  
            *n_in = 0;  
        free( consensus_max );  
    }  
  
    //RANSAC算法结束:恢复特征点中被更改的数据域feature_data,并返回变换矩阵M  
end:  
    for( i = 0; i < nm; i++ )  
    {  
        //利用宏feat_ransac_data来提取matched[i]中的feature_data成员并转换为ransac_data格式的指针  
        rdata = feat_ransac_data( matched[i] );  
        //恢复feature_data成员的以前的值  
        matched[i]->feature_data = rdata->orig_feat_data;  
        free( rdata );//释放内存  
    }  
    free( matched );  
  
    return M;//返回求出的变换矩阵M  
}  




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RANSAC算法实现去除误匹配并计算拼接矩阵-随笔 的相关文章

  • macOS SFTP 传输文件

    FileZilla 参考 Download FileZilla Client for macOS
  • v1.21.0-rc3 lotus chain prune hot-moving

    lotus span class token operator span version lotus version span class token number 1 21 span span class token number 0 s
  • iPhone卡死 强制重启iPhone 14

    粘贴无法取消 xff0c iPhone卡死 xff0c 无法操作 iPhone 强制重启 无法滑动来关机 按一下 音量键 43 键 xff08 不需要长按 xff09 按一下 音量键 键 xff08 不需要长按 xff09 长按 电源键 大
  • Mainnet endpoint Filecoin Lotus api

    infura ENDPOINTS https span class token punctuation span span class token operator span span class token operator span 2
  • sed 将匹配的整行替换

    sed 将匹配的整行替换 sed 39 span class token operator span pattern span class token operator span c replacement line 39 file pat
  • Spring的Java配置方式

    Spring的发展 Spring1 x 时代 在Spring1 x时代 xff0c 都是通过xml文件配置bean xff0c 随着项目的不断扩大 xff0c 需要将xml配置分放到不同的配置文件中 xff0c 需要频繁的在java类和xm
  • Keychron K3 Pro

    Keychron K3 Pro Keychron K3 Pro A31 连接蓝牙2 更改键盘背光模式和快速关闭开启键盘背光3 调整键盘背光亮度4 调整背光速度5 查看电池电量 Keychron K3 Pro A3 1 连接蓝牙 长按fn 4
  • miner14 export

    lotus chain export span class token operator span recent span class token operator span stateroots span class token oper
  • iTerm2 恢复窗口

    退出应用程序时关闭窗口
  • Homebrew 安装

    Homebrew Homebrew 安装添加 Homebrew 到 PATH在当前终端设置环境变量 运行参考 Homebrew 安装 span class token operator span bin span class token o
  • sed 使用#作为分隔符

    sed 将 bin sh替换为bash需要使用 进行转义 以匹配 字符使用 作为分隔符 将 bin sh替换为bash 需要使用 进行转义 以匹配 字符 sed 39 s span class token operator span spa
  • 华为 USG6625E 防火墙

    服务列表 需要设置目标端口
  • baseDeltaSeconds PROPAGATION_DELAY_SECS 设置传播延迟时间

    设置lotus传播延迟 默认区块传播延迟10秒设置环境变量参考 xff1a 默认区块传播延迟10秒 span class token string 34 baseDeltaSeconds 34 span span class token p
  • Ubuntu 18.04禁止内核更新

    apt span class token operator span mark showhold linux span class token operator span headers span class token operator
  • AMD64的4个架构级别 v1 v2 v3 v4

    查看cpu支持指令 lscpu span class token operator span grep Flags 例如 GOAMD64 61 v3 使用 AVX2 查看cpu是否支持指令 lscpu span class token op
  • Ubuntu 18.04 安装 ffmpeg

    Ubuntu 18 04 安装 ffmpeg wget http span class token punctuation span span class token operator span span class token opera
  • 图形界面无法启动的解决办法

    错误提示信息 xff1a log file 34 var log xorg 0 log 34 Using config file 34 etc X11 Xorg conf 34 gt error bad lenght in compatma
  • SUSE Linux Ubuntu 下安装mysql遇到的问题一。

    用的是阿里云的新服务器 xff0c 用的是Ubuntu不是Contos的在安装mysql的时候遇到了一些问题 在此记录一下 1 创建目录用来下载安装包 命令 xff1a mkdir usr local software 文件目录根据没有固定
  • 是时候拥抱ViewBinding了~

    是时候拥抱ViewBinding了 xff01 xff01 一 前言二 初识ViewBinding三 拥抱ViewBinding3 1 环境要求3 2 开启ViewBinding功能3 3 Activity中ViewBinding的使用3
  • linux下以rpm包安装mysql

    目录 下载 上传解压 安装 编辑my cnf配置文件 启动数据库 修改初始密码 授权远程登录 常见问题 下载 访问以下地址下载对应操作系统下所需的版本 https downloads mysql com archives community

随机推荐

  • sizeof用法详解

    一 sizeof是什么 sizeof是C语言的一种单目操作符 xff0c 如C语言的其他操作符 43 43 等 它并不是函数 sizeof操作符以字节形式给出了其操作数的存储大小 操作数可以是一个表达式或括在括号内的类型名 操作数的存储大小
  • 【ftp2ftp】文件以字节流的形式冲FTP1传输到FTP2,中间出现文件传输失败的问题(只传输了一半,文件损坏)

    文件传输问题 需求实现逻辑问题代码简述正确的代码代码合集 需求 代码直接实现两个ftp之间的文件相互传输 实现逻辑 ftp1的file转变成inputStream inputStream转变为字符集byte 字符集写入ftp2的output
  • 【Java】反编译Mac版Charles,修改一些功能

    目录 反编译jar使用javassist修改目标class替换CharlesContext class 参考 最近学习HTTP代理相关资料时 xff0c 偶然间发现Mac上的charles是用java实现的 xff0c 且很好破解 xff0
  • 为什么说TCP是面向流的协议?而UDP是面向数据报的协议?

    问题 经常能听人说 xff1a TCP是面向流的协议 xff0c 而UDP是面向数据报的协议 从字面理解上来说 xff0c 似懂非懂 每次都不是能彻底明白什么是流 xff0c 什么是数据报 xff1f 在大家眼里 xff0c 网络报文都是I
  • 【面试题】N级台阶(比如100级),每次可走1步或者2步,求总共有多少种走法?

    走台阶算法 xff08 本质上是斐波那契数列 xff09 在面试中常会遇到 xff0c 描述就如题目那样 xff1a 总共100级台阶 xff08 任意级都行 xff09 xff0c 小明每次可选择走1步 2步或者3步 xff0c 问走完这
  • Java访问权限修饰符的区别

    Java有四种访问权限 xff0c 其中三种有访问权限修饰符 xff0c 分别为private xff0c public和protected xff0c 还有一种不带任何修饰符 xff1a private Java语言中对访问权限限制的最窄
  • “二分查找”算法的时间复杂度

    算法的时间复杂度无非就是for while等包含起来的基本运算单元的循环次数 1 二分查找 二分查找 xff08 binary search xff09 xff0c 也称作折半查找 xff08 half interval search xf
  • ORA-12547与在 root 下执行 Oracle 程序时找不到 libclntsh.so.11.1解决方案

    在 root 下执行 Oracle 程序时找不到 libclntsh so 11 1时 如图所示libclntsh so 11 1 61 gt not found 解决方法 xff1a locate libclntsh so 11 1 找到
  • 【D3.js】力导向布局 + 圆形图片展示的人物关系

    前言 使用d3的力学图 xff08 力导向图 xff09 与生活中常见的人物关系图结合 xff0c 已经有了很好的例子 xff1a D3 js 进阶系列 2 0 力学图 43 人物关系图 xff0c 博主实现了下面这种样式 xff0c 已经
  • 【Android】adb 查看所有程序包名

    adb shell pm span class hljs keyword list span packages 列出所有的包名 adb shell pm list packages span class hljs label package
  • 【算法】大数乘法问题及其高效算法

    题目 编写两个任意位数的大数相乘的程序 xff0c 给出计算结果 比如 xff1a 题目描述 xff1a 输出两个不超过100位的大整数的乘积 输入 xff1a 输入两个大整数 xff0c 如1234567 和 123 输出 xff1a 输
  • 【算法】如何判断链表有环

    如何判断单链表是否存在环 有一个单向链表 xff0c 链表当中有可能出现 环 xff0c 就像题图这样 如何用程序判断出这个链表是有环链表 xff1f 不允许修改链表结构 时间复杂度O n xff0c 空间复杂度O 1 方法一 穷举遍历 方
  • 【Android】移动端接入Cronet实践

    移动端接入Cronet实践 QUIC协议获取Chromium源码编译CronetAndroid iOS buildsDesktop builds targets the current OS Running the ninja files生
  • Linux系统下安装Java环境

    目录 测试环境 下载JDK 终端模拟软件 安装前准备 tar包的安装方法 tar包的卸载 rpm包的安装方法 rpm包的卸载 测试环境 LInux系统版本 xff1a CentOS 7 64位 终端模拟软件 xff1a Xshell 6 J
  • 【Hexo】Hexo个人博客绑定域名

    Hexo个人博客绑定域名 当我们在用hexo搭建了个人博客之后 xff0c 用username github io访问难免有些奇怪 xff0c 下面就花3分钟时间对如何绑定个人域名进行描述 我这边是在阿里云买的一个域名 xff0c ycbl
  • 生产者消费者的代码实现

    当消费者获得的数据为大写字母时 xff0c 则把大写字母转换成小写字母 xff0c 并显示 xff1b 当消费者获得的数据为小写字母时 xff0c 则把小写字母转换成大写字母 xff0c 并显示 xff1b 当消费者获得的数据为字符0 1
  • 基于RobHess的SIFT图像拼接知识点随笔

    1 SIFT算法具有尺度不变性在于构建的高斯尺度空间 xff1b 2 SIFT算法具有旋转不变性在于特征方向向量 xff1b 3 K d数以图像特征点的128维特征描述子均值为依据进行划分 构建 xff1b 4 特征点匹配是一个图像的所有特
  • 最小二乘法及OpenCv函数

    1 最小二乘法 我们以最简单的一元线性模型来解释最小二乘法 什么是一元线性模型呢 xff1f 监督学习中 xff0c 如果预测的变量是离散的 xff0c 我们称其为分类 xff08 如决策树 xff0c 支持向量机等 xff09 xff0c
  • Linux服务器网络不通情况分析以及常见检查方法

    在实际运维过程中 xff0c 经常会遇到网路不通的问题 xff0c 一般此类网络不通的问题都是业务端到端的排查 本文从后端linux服务器端自查是否服务器问题 通过多年的运维经验总结 xff0c 服务器端问题导致网络不通 xff0c 大致分
  • RANSAC算法实现去除误匹配并计算拼接矩阵-随笔

    1 RANSAC算法实现去除误匹配并计算拼接矩阵流程 1 从样本集中随机抽选一个RANSAC样本 xff0c 即4个匹配点对 xff08 至少4个匹配点对 xff0c 才能计算出3 3变换矩阵 xff09 xff1b 2 计算当错误概率为0