图像尺度空间理论_16位灰度图像

图像尺度空间理论_16位灰度图像《SIFT原理与源码分析》系列文章索引:http://blog.csdn.net/xiaowei_cqu/article/details/8069548尺度空间理论自然界中的物体随着观测尺度不同有不同的表现形态。例如我们形容建筑物用“米”,观测分子、原子等用“纳米”。更形象的例子比如Google地图,滑动鼠标轮可以改变观测地图的尺度,看到的地图绘制也不同;还有电影中的拉

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

《SIFT原理与源码分析》系列文章索引:http://blog.csdn.net/xiaowei_cqu/article/details/8069548

尺度空间理论


自然界中的物体随着观测
尺度不同有不同的表现形态。例如我们形容建筑物用“米”,观测分子、原子等用“纳米”。更形象的例子比如
Google地图,滑动鼠标轮可以改变观测地图的尺度,看到的地图绘制也不同;还有电影中的拉伸镜头等等……
尺度空间中各尺度图像的模糊程度逐渐变大,能够模拟人在距离目标由近到远时目标在视网膜上的形成过程。


尺度越大图像越模糊。


为什么要讨论尺度空间?

用机器视觉系统分析未知场景时,计算机并不预先知道图像中物体的尺度。我们需要同时考虑图像在多尺度下的描述,获知感兴趣物体的
最佳尺度。另外如果不同的尺度下都有同样的关键点,那么在不同的尺度的输入图像下就都可以检测出来关键点匹配,也就是
尺度不变性

图像的尺度空间表达就是图像在所有尺度下的描述。

尺度空间表达与金字塔多分辨率表达

高斯模糊

高斯核是唯一可以产生多尺度空间的核(《Scale-space theory: A basic tool for analysing structures at different scales》)。一个图像的尺度空间L(x,y,σ) ,定义为原始图像I(x,y)与一个可变尺度的2维高斯函数G(x,y,σ)卷积运算。 

二维空间高斯函数:

图像尺度空间理论_16位灰度图像

尺度空间:

图像尺度空间理论_16位灰度图像

尺度是自然客观存在的,不是主观创造的。高斯卷积只是表现尺度空间的一种形式。

二维空间高斯函数是等高线从中心成正太分布的同心圆:

图像尺度空间理论_16位灰度图像

分布不为零的点组成卷积阵与原始图像做变换,即每个像素值是周围相邻像素值的高斯平均。一个5*5的高斯模版如下所示:

图像尺度空间理论_16位灰度图像



高斯模版是圆对称的
,且卷积的结果使原始像素值有最大的权重,距离中心越远的相邻像素值权重也越小。


在实际应用中,在计算高斯函数的离散近似时,在大概

距离之外的像素都可以看作不起作用,这些像素的计算也就可以忽略。所以,通常程序只计算
(6σ+1)*(6σ+1)
就可以保证相关像素影响。

高斯模糊另一个很厉害的性质就是线性可分:使用二维矩阵变换的高斯模糊可以通过在水平和竖直方向各进行一维高斯矩阵变换相加得到。

图像尺度空间理论_16位灰度图像

O(N^2*m*n)次乘法就缩减成了O(N*m*n)+O(N*m*n)次乘法。(N为高斯核大小,m,n为二维图像高和宽)

其实高斯这一部分只需要简单了解就可以了,在OpenCV也只需要一句代码:

[cpp] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. GaussianBlur(dbl, dbl, Size(), sig_diff, sig_diff);  

我这里详写了一下是因为这块儿对分析算法效率比较有用,而且高斯模糊的算法真的很漂亮~

金字塔多分辨率

金字塔是早期图像多尺度的表示形式。图像金字塔化一般包括两个步骤:使用低通滤波器平滑图像;对平滑图像进行降采样(通常是水平,竖直方向1/2),从而得到一系列尺寸缩小的图像。

图像尺度空间理论_16位灰度图像

上图中(a)是对原始信号进行低通滤波,(b)是降采样得到的信号。

而对于二维图像,一个传统的金字塔中,每一层图像由上一层分辨率的长、宽各一半,也就是四分之一的像素组成:

图像尺度空间理论_16位灰度图像

多尺度和多分辨率

尺度空间表达和金字塔多分辨率表达之间最大的不同是:

  • 尺度空间表达是由不同高斯核平滑卷积得到,在所有尺度上有相同的分辨率;
  • 而金字塔多分辨率表达每层分辨率减少固定比率。
所以,金字塔多分辨率生成较快,且占用存储空间少;而多尺度表达随着尺度参数的增加冗余信息也变多。
多尺度表达的优点在于图像的局部特征可以用简单的形式在不同尺度上描述;而金字塔表达没有理论基础,难以分析图像局部特征。

DoG(Difference of Gaussian)


高斯拉普拉斯LoG金字塔

结合尺度空间表达和金字塔多分辨率表达,就是在使用尺度空间时使用金字塔表示,也就是计算机视觉中最有名的拉普拉斯金子塔(
《The Laplacian pyramid as a compact image code》)。
高斯拉普拉斯LoG(Laplace of Guassian)算子就是对高斯函数进行拉普拉斯变换:
图像尺度空间理论_16位灰度图像

核心思想还是高斯,这个不多叙述。

高斯差分DoG金字塔

DoG(Difference of Gaussian)其实是对高斯拉普拉斯LoG的近似,也就是对
图像尺度空间理论_16位灰度图像的近似。SIFT算法建议,在某一尺度上的特征检测可以通过对两个相邻高斯尺度空间的图像相减,得到DoG的响应值图像D(x,y,σ)。然后仿照LoG方法,通过对响应值图像D(x,y,σ)进行局部最大值搜索,在空间位置和尺度空间定位局部特征点。其中:
图像尺度空间理论_16位灰度图像

k为相邻两个尺度空间倍数的常数。
图像尺度空间理论_16位灰度图像

上图中(a)是DoG的三维图,(b)是DoG与LoG的对比。

金字塔构建


构建高斯金字塔

为了得到DoG图像,先要构造高斯金字塔。我们回过头来继续说高斯金字塔~
高斯金字塔在多分辨率金字塔简单
降采样基础上加了高斯滤波,也就是对金字塔每层图像用不同参数的σ做高斯模糊,使得每层金字塔有多张高斯模糊图像。金字塔每层多张图像合称为一组(Octave),每组有多张(也叫层Interval)图像。另外,降采样时,金字塔上边一组图像的第一张图像(最底层的一张)是由前一组(金字塔下面一组)图像的倒数第三张隔点采样得到。
图像尺度空间理论_16位灰度图像


以下是OpenCV中构建高斯金字塔的代码,我加了相应的注释:
[cpp] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. // 构建nOctaves组(每组nOctaves+3层)高斯金字塔  
  2. void SIFT::buildGaussianPyramid( const Mat& base, vector<Mat>& pyr, int nOctaves ) const  
  3. {  
  4.     vector<double> sig(nOctaveLayers + 3);  
  5.     pyr.resize(nOctaves*(nOctaveLayers + 3));  
  6.   
  7.     // precompute Gaussian sigmas using the following formula:  
  8.     //  \sigma_{total}^2 = \sigma_{i}^2 + \sigma_{i-1}^2、  
  9.     // 计算对图像做不同尺度高斯模糊的尺度因子  
  10.     sig[0] = sigma;  
  11.     double k = pow( 2., 1. / nOctaveLayers );  
  12.     forint i = 1; i < nOctaveLayers + 3; i++ )  
  13.     {  
  14.         double sig_prev = pow(k, (double)(i-1))*sigma;  
  15.         double sig_total = sig_prev*k;  
  16.         sig[i] = std::sqrt(sig_total*sig_total – sig_prev*sig_prev);  
  17.     }  
  18.   
  19.     forint o = 0; o < nOctaves; o++ )  
  20.     {  
  21.         // DoG金子塔需要nOctaveLayers+2层图像来检测nOctaves层尺度  
  22.         // 所以高斯金字塔需要nOctaveLayers+3层图像得到nOctaveLayers+2层DoG金字塔  
  23.         forint i = 0; i < nOctaveLayers + 3; i++ )  
  24.         {  
  25.             // dst为第o组(Octave)金字塔  
  26.             Mat& dst = pyr[o*(nOctaveLayers + 3) + i];  
  27.             // 第0组第0层为原始图像  
  28.             if( o == 0  &&  i == 0 )  
  29.                 dst = base;  
  30.               
  31.             // base of new octave is halved image from end of previous octave  
  32.             // 每一组第0副图像时上一组倒数第三幅图像隔点采样得到  
  33.             else if( i == 0 )  
  34.             {  
  35.                 const Mat& src = pyr[(o-1)*(nOctaveLayers + 3) + nOctaveLayers];  
  36.                 resize(src, dst, Size(src.cols/2, src.rows/2),  
  37.                        0, 0, INTER_NEAREST);  
  38.             }  
  39.             // 每一组第i副图像是由第i-1副图像进行sig[i]的高斯模糊得到  
  40.             // 也就是本组图像在sig[i]的尺度空间下的图像  
  41.             else  
  42.             {  
  43.                 const Mat& src = pyr[o*(nOctaveLayers + 3) + i-1];  
  44.                 GaussianBlur(src, dst, Size(), sig[i], sig[i]);  
  45.             }  
  46.         }  
  47.     }  
  48. }  

高斯金字塔的组数为:
图像尺度空间理论_16位灰度图像

代码10-17行是计算高斯模糊的系数σ,具体关系如下:
图像尺度空间理论_16位灰度图像

其中,σ为尺度空间坐标,s为每组中层坐标,σ0为初始尺度,S为每组层数(一般为3~5)。根据这个公式,我们可以得到金字塔组内各层尺度以及组间各图像尺度关系。

组内相邻图像尺度关系:
图像尺度空间理论_16位灰度图像

相邻组间尺度关系:
图像尺度空间理论_16位灰度图像

所以,
相邻两组的同一层尺度为2倍的关系

最终尺度序列总结为:
图像尺度空间理论_16位灰度图像

o为金字塔组数,n为每组金字塔层数。

构建DoG金字塔

构建高斯金字塔之后,就是用金字塔相邻图像相减构造DoG金字塔。
图像尺度空间理论_16位灰度图像


下面为构造DoG的代码:
[cpp] 
view plain
copy
在CODE上查看代码片
派生到我的代码片

  1. // 构建nOctaves组(每组nOctaves+2层)高斯差分金字塔  
  2. void SIFT::buildDoGPyramid( const vector<Mat>& gpyr, vector<Mat>& dogpyr ) const  
  3. {  
  4.     int nOctaves = (int)gpyr.size()/(nOctaveLayers + 3);  
  5.     dogpyr.resize( nOctaves*(nOctaveLayers + 2) );  
  6.   
  7.     forint o = 0; o < nOctaves; o++ )  
  8.     {  
  9.         forint i = 0; i < nOctaveLayers + 2; i++ )  
  10.         {  
  11.             // 第o组第i副图像为高斯金字塔中第o组第i+1和i组图像相减得到  
  12.             const Mat& src1 = gpyr[o*(nOctaveLayers + 3) + i];  
  13.             const Mat& src2 = gpyr[o*(nOctaveLayers + 3) + i + 1];  
  14.             Mat& dst = dogpyr[o*(nOctaveLayers + 2) + i];  
  15.             subtract(src2, src1, dst, noArray(), CV_16S);  
  16.         }  
  17.     }  
  18. }  

这个比较简单,就是一个
subtract()函数。


至此,SIFT第一步就完成了。参见《SIFT原理与源码分析

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/184156.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • mysql的访问端口是什么意思_数据库端口是什么端口号

    连接SQL数据库时,不指定端口号时是不是就默认端口号是1433?SQLServer服务器默认监听的端口号是1433,如果服务器的端口不是1433,简单的链接方法可以在服务器IP地址后面写逗号和制定端口,例如:如何设置sqlserver端口号可以在’配置工具’–>’SQLSERVER配置管理器’—>’SQLSERVER网络配置’—>’实例名。协议’–>…

  • jmespath(2)投影Projections「建议收藏」

    jmespath(2)投影Projections「建议收藏」投影投影是JMESPath的关键特性之一。它允许您将表达式应用于元素集合。有五种投影:列表投影切片投影对象投影展平投影过滤投影处理投影需要注意的点投影分为两个步骤。左侧(LHS)创建一

  • python modis数据拼接_python读取modis数据

    python modis数据拼接_python读取modis数据本期记录只上干活,废话不多说,主要是后面与HEG配合使用,实现一系列研究与反演操作。python环境:Python3.5.2+Pycharm模块包:pyhdf安装方法(命令行输入):pipinstallpyhdf一、获取hdf数据集:frompyhdf.SDimportSDHDF_FILR_URL=”E:\Persona_project\Py-Program\RS\modis\M…

    2022年10月30日
  • 记一次post请求参数太长导致的400报错

    记一次post请求参数太长导致的400报错背景:springboot2.1.1+vue2.6.11+iview3.3.0+axios0.18.1这个接口是接收前台图文编辑器的内容,插入数据库,当接收图文内容的字段过长时,就抛出400网上查了很多解决方案,都是从修改配置方面着手,试过如下:还有说debug源码的,参数格式错的……各种方法试过,大好青春浪费在试错上了。不说了,上答案:只修改了传参方式,结果如下:这里有一个关键,后台传参要用@RequestBody至于原因我就不说了,小伙伴可以自行搜索vueda

  • ORM初识和数据库操作

    ORM简介ORM概念及特点为什么用ORMORM的作用ORM的优劣势ORM的优势ORM的劣势ORM总结映射关系ORM的俩大功能ORM链接数据库创建表之前的准备工作1、自己创建数据

  • SQL中row_number() over(partition by)详解「建议收藏」

    SQL中row_number() over(partition by)详解「建议收藏」row_number语法ROW_NUMBER()函数将针对SELECT语句返回的每一行,从1开始编号,赋予其连续的编号。在查询时应用了一个排序标准后,只有通过编号才能够保证其顺序是一致的,当使用ROW_NUMBER函数时,也需要专门一列用于预先排序以便于进行编号partitionby关键字是分析性函数的一部分,它和聚合函数不同的地方在于它能返回一个分组中的多条记录,而聚合函数一般只有一条反…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号