一、前言

稀疏表示是自上世纪90年代开始,从人眼的视觉感受野获得启示,逐渐被人们所研究。现在已经发展为一种重要的信息表示方法。所谓稀疏表示是指,一个信号在过完备字典中,可以由少数个原子线性表达,

其数学模型可以表达如下:

这个数学模型解算是一个NP-hard问题,也就是说只能通过穷举去获得最优解,其时间复杂度很大,几乎无法获得其精确的解算。在这种情况下,我们常用贪婪算法去获得该模型的次最优解。本文介绍一种主流的贪婪算法——

正交匹配追踪(OMP)。

二、OMP算法

贪婪算法的核心是每次从字典的原子中选择一个最优原子来表示原始的信号。贪婪算法最大的缺点是,在贪婪算法的思想里,认为全局最优是每个局部最优得到的,这实际上很容易进入局部最优解,无法得到数据的全局最优解。

OMP作为贪婪算法中比较具有代表性的算法,其主要思想在于以下两点:

1 认为字典原子在信号投影中的越大,对信号的描述越好;

2 每一次选择的原子都与之前的原子正交。

介于以上两点,OMP算法的描述如下:

上图是从网上摘抄下来的。大概就是那样。但是值得注意的是:这样的OMP算法在解算的时候其效果往往没有ORMP算法好,目前好多人说的OMP算法其实质往往是ORMP算法。

比如:开源的工具箱SPAMS上的OMP算法解算部分,其核心就是ORMP算法。ORMP算法相比如OMP算法的不同在于,在计算完残差后对字典原子进行了另一个的拉伸(具体拉伸见后面代码部分),如下图:

三、SOMP算法

SOMP算法又叫同步OMP算法,主要思想为:相似的原子具有相同的稀疏特性。因此在对相似原子进行稀疏表示时,假设稀疏原子位于相同的位置,及其在过完备字典的选择的原子相同,OMP算法是SOMP算法在原始信号为一个原子

时的特殊情况。OMP算法可以统一到SOMP算法当中,其解算流程几乎同OMP算法部分。

四、代码实现

代码如下:

 cv::Mat ormpSparseRepresentation::ompSparseL2(const cv::Mat Dict, const cv::Mat Y, const int K)
{
int r = Dict.rows;
int c = Dict.cols;
int n = Y.cols;
cv::Mat ERR(r,,CV_32F);
ERR = Y;
int size[] = {c,n};
cv::Mat A = cv::Mat(,size,CV_32F,cv::Scalar(.f));
QVector<int> index;
cv::Mat U = cv::Mat::ones(,c,CV_32F);
cv::Mat tmpA;
for(int i = ;i<K;i++)
{
cv::Mat S = ERR.t()*Dict;
cv::pow(S,,S);
if(S.rows != )
cv::reduce(S,S,,CV_REDUCE_SUM);
cv::sqrt(S,S);
S = S/U;
if(i!=)
{
for(int j = ;j<index.size();j++)
{
S.at<float>(,index[j]) = .f;
}
} cv::Point maxLoc;
cv::minMaxLoc(S,NULL,NULL,NULL,&maxLoc);
int pos = maxLoc.x;
index.append(pos); cv::Mat subDict;
getColDictFormIndex(Dict,index,subDict); cv::Mat invSubDict;
cv::invert(subDict,invSubDict,cv::DECOMP_SVD); tmpA = invSubDict*Y;
ERR = Y - subDict*tmpA; cv::Mat Dict_T_Dict;
cv::mulTransposed(subDict,Dict_T_Dict,);
cv::Mat invDict_T_Dict;
cv::invert(Dict_T_Dict,invDict_T_Dict,cv::DECOMP_SVD); cv::Mat P = (cv::Mat::eye(r,r,CV_32F) - subDict*invDict_T_Dict*subDict.t())*Dict;
cv::pow(P,,P);
cv::reduce(P,P,,CV_REDUCE_SUM);
cv::sqrt(P,U);
}
for(int i = ;i<K;i++)
{
int tmpC = index[i];
const float *inP=tmpA.ptr<float>(i);
float *outP=A.ptr<float>(tmpC);
for(int j = ;j<n;j++)
{
outP[j] = inP[j];
}
}
return A;
}
 void ormpSparseRepresentation::getColDictFormIndex(const cv::Mat Dict, const QVector<int> index, cv::Mat &res)
{
if(index.size() == )
return;
if(!Dict.data)
return; int r = Dict.rows;
int c = index.size(); cv::Mat Dict_T;
cv::transpose(Dict,Dict_T); cv::Mat res_T = cv::Mat(c,r,Dict.type()); for(int i = ;i<index.size();i++)
{
int tmpC = index[i];
const float *inP=Dict_T.ptr<float>(tmpC);
float *outP=res_T.ptr<float>(i);
for(int j = ;j<r;j++)
{
outP[j] = inP[j];
}
}
cv::transpose(res_T,res);
res_T.release();
Dict_T.release();
}

7. 稀疏表示之OMP,SOMP算法及openCV实现的更多相关文章

  1. 稀疏自动编码之反向传播算法(BP)

    假设给定m个训练样本的训练集,用梯度下降法训练一个神经网络,对于单个训练样本(x,y),定义该样本的损失函数: 那么整个训练集的损失函数定义如下: 第一项是所有样本的方差的均值.第二项是一个归一化项( ...

  2. (转载)利用SIFT和RANSAC算法(openCV框架)实现物体的检测与定位,并求出变换矩阵(findFundamentalMat和findHomography的比较) 置顶

    原文链接:https://blog.csdn.net/qq_25352981/article/details/46914837#commentsedit 本文目标是通过使用SIFT和RANSAC算法, ...

  3. SLAM: 图像角点检测的Fast算法(OpenCV文档)

    官方链接:http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_fast/py_fast.html#fast-algorithm- ...

  4. SAD算法在opencv上的实现代码(c++)

    #include <opencv2/opencv.hpp>#include <opencv2/core/core.hpp>#include <opencv2/highgu ...

  5. 稀疏分解中的MP与OMP算法

    MP:matching pursuit匹配追踪 OMP:正交匹配追踪 主要介绍MP与OMP算法的思想与流程,解释为什么需要引入正交? !!今天发现一个重大问题,是在读了博主的正交匹配追踪(OMP)在稀 ...

  6. OMP算法代码学习

    正交匹配追踪(OMP)算法的MATLAB函数代码并给出单次测试例程代码 测量数M与重构成功概率关系曲线绘制例程代码 信号稀疏度K与重构成功概率关系曲线绘制例程代码   参考来源:http://blog ...

  7. 浅谈压缩感知(二十一):压缩感知重构算法之正交匹配追踪(OMP)

    主要内容: OMP的算法流程 OMP的MATLAB实现 一维信号的实验与结果 测量数M与重构成功概率关系的实验与结果 稀疏度K与重构成功概率关系的实验与结果 一.OMP的算法流程 二.OMP的MATL ...

  8. MP算法、OMP算法及其在人脸识别的应用

    主要内容: 1.MP算法 2.OMP算法 3.OMP算法的matlab实现 4.OMP在压缩感知和人脸识别的应用 一.MP(Matching Pursuits)与OMP(Orthogonal Matc ...

  9. scikit-learn 线性回归算法库小结

    scikit-learn对于线性回归提供了比较多的类库,这些类库都可以用来做线性回归分析,本文就对这些类库的使用做一个总结,重点讲述这些线性回归算法库的不同和各自的使用场景. 线性回归的目的是要得到输 ...

随机推荐

  1. Android Xfermode 实战 实现圆形、圆角图片

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/42094215,本文出自:[张鸿洋的博客] 1.概述 其实这篇本来准备Androi ...

  2. post请求和get请求的区别

    1:如果表单是以post方式发送,那么表单中的数据会放在请求报文体中,发送到服务端.但是如果是以get方式提交表单,那么表单中用户输入的数据都是以URL地址的方式发送到服务端. 2:在服务端接收数据时 ...

  3. KindEditor放在包含模版页的页面里不显示解决方案

    由于用了母版页,内容页服务器控件(是服务器控件哦)的id会被重写,我这里运行中查看源代码,控件的id变成了“ContentPlaceHolder1_content1”. <asp:TextBox ...

  4. (转) 值不能为空。参数名viewinfo(microsoft.sqlserver.management.sqlstudio.explorer)

    打开MSSQL 2008 R2的时候,展开数据库都显示以下的错误提示: 值不能为空.参数名viewinfo(microsoft.sqlserver.management.sqlstudio.explo ...

  5. iOS_SN_Xcode内存泄露调试

    用Xcode进行内存调试有两种方法: 1.静态方法 2.动态方法 静态方法是直接在Xcode的菜单栏中选择product-->analyze 如截图所示. 之后会看到Xcode的编译状态上会有如 ...

  6. iOS_SN_Socket - AsyncSocket

    转载文章,原地址:http://yimouleng.com/2015/02/04/Socket-AsyncSocket/ 一.前言 公司的项目用到了Socket编程,之前在学习的过程当中,用到的更多的 ...

  7. NDK编译Python2.7.5

    [背景] 网上有一些ndk编译python的做法,但按照教程做总是不成功,可能是环境版本不一样,导致很多地方的配置都不成功. 网上的教程大多只有做法,没有解释,即使按照教程编译成功,很多细节都不知道为 ...

  8. MFC的初始化过程和消息映射技术

    1.删除#include <windows.h>--win32中的-(使用win32工程编程mfc必须删除) 添加#include <afxwin.h> -- mfc中的- 2 ...

  9. 有关SetTimer函数的用法

    1 )用WM_TIMER来设置定时器 先请看SetTimer这个API函数的原型 UINT_PTR SetTimer( HWND hWnd, // 窗口句柄 UINT_PTR nIDEvent, // ...

  10. Convert.ToInt32()和int.Parse()的区别

    (1)Convert.ToInt32(null)会返回0而不会报异常,但int.Parse(null)则会产生异常 (2)Convert.ToInt32("")和int.Parse ...