7. 稀疏表示之OMP,SOMP算法及openCV实现

一、前言

稀疏表示是自上世纪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算法部分。

四、代码实现

代码如下:

 1 cv::Mat ormpSparseRepresentation::ompSparseL2(const cv::Mat Dict, const cv::Mat Y, const int K)
 2 {
 3     int r = Dict.rows;
 4     int c = Dict.cols;
 5     int n = Y.cols;
 6     cv::Mat ERR(r,1,CV_32F);
 7     ERR = Y;
 8     int size[] = {c,n};
 9     cv::Mat A = cv::Mat(2,size,CV_32F,cv::Scalar(0.f));
10     QVector<int> index;
11     cv::Mat U = cv::Mat::ones(1,c,CV_32F);
12     cv::Mat tmpA;
13     for(int i = 0;i<K;i++)
14     {
15         cv::Mat S = ERR.t()*Dict;
16         cv::pow(S,2,S);
17         if(S.rows != 1)
18             cv::reduce(S,S,0,CV_REDUCE_SUM);
19         cv::sqrt(S,S);
20         S = S/U;
21         if(i!=0)
22         {
23             for(int j = 0;j<index.size();j++)
24             {
25                 S.at<float>(0,index[j]) = 0.f;
26             }
27         }
28
29         cv::Point maxLoc;
30         cv::minMaxLoc(S,NULL,NULL,NULL,&maxLoc);
31         int pos = maxLoc.x;
32         index.append(pos);
33
34         cv::Mat subDict;
35         getColDictFormIndex(Dict,index,subDict);
36
37         cv::Mat invSubDict;
38         cv::invert(subDict,invSubDict,cv::DECOMP_SVD);
39
40         tmpA = invSubDict*Y;
41         ERR = Y - subDict*tmpA;
42
43         cv::Mat Dict_T_Dict;
44         cv::mulTransposed(subDict,Dict_T_Dict,1);
45         cv::Mat invDict_T_Dict;
46         cv::invert(Dict_T_Dict,invDict_T_Dict,cv::DECOMP_SVD);
47
48         cv::Mat P = (cv::Mat::eye(r,r,CV_32F) - subDict*invDict_T_Dict*subDict.t())*Dict;
49         cv::pow(P,2,P);
50         cv::reduce(P,P,0,CV_REDUCE_SUM);
51         cv::sqrt(P,U);
52     }
53     for(int i = 0;i<K;i++)
54     {
55         int tmpC = index[i];
56         const float *inP=tmpA.ptr<float>(i);
57         float *outP=A.ptr<float>(tmpC);
58         for(int j = 0;j<n;j++)
59         {
60             outP[j] = inP[j];
61         }
62     }
63     return A;
64 }

 1 void ormpSparseRepresentation::getColDictFormIndex(const cv::Mat Dict, const QVector<int> index, cv::Mat &res)
 2 {
 3     if(index.size() == 0)
 4         return;
 5     if(!Dict.data)
 6         return;
 7
 8     int r = Dict.rows;
 9     int c = index.size();
10
11     cv::Mat Dict_T;
12     cv::transpose(Dict,Dict_T);
13
14     cv::Mat res_T = cv::Mat(c,r,Dict.type());
15
16     for(int i = 0;i<index.size();i++)
17     {
18         int tmpC = index[i];
19         const float *inP=Dict_T.ptr<float>(tmpC);
20         float *outP=res_T.ptr<float>(i);
21         for(int j = 0;j<r;j++)
22         {
23             outP[j] = inP[j];
24         }
25     }
26     cv::transpose(res_T,res);
27     res_T.release();
28     Dict_T.release();
29 }

时间: 2024-10-13 02:50:51

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

人脸识别---基于深度学习和稀疏表达的人脸识别算法

介绍 基于深度学习和稀疏表达的人脸识别算法 1 利用VGGFace提取人脸特征 2 PCA对人脸特征进行降维 3 稀疏表达的人脸匹配 Code 1 介绍 本文将介绍一种基于深度学习和稀疏表达的人脸识别算法.首先,利用深度学习框架(VGGFace)提取人脸特征:其次,利用PCA对提取的特征进行降维:最后,利用稀疏表达分类实现特征匹配.我采用CMC曲线评价在AR数据库上的识别性能.最后我还提供了整个过程的code. 2 基于深度学习和稀疏表达的人脸识别算法 2.1 利用VGGFace提取人脸特征 下

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

假设给定m个训练样本的训练集,用梯度下降法训练一个神经网络,对于单个训练样本(x,y),定义该样本的损失函数: 那么整个训练集的损失函数定义如下: 第一项是所有样本的方差的均值.第二项是一个归一化项(也叫权重衰减项),该项是为了减少权连接权重的更新速度,防止过拟合. 我们的目标是最小化关于 W 和 b 的函数J(W,b). 为了训练神经网络,把每个参数 和初始化为很小的接近于0的随机值(例如随机值由正态分布Normal(0,ε2)采样得到,把 ε 设为0.01), 然后运用批量梯度下降算法进行优

稀疏表达和字典学习算法

LCKSVD  Label Consistent K-SVD: Learning A Discriminative Dictionary for Recognition   http://www.umiacs.umd.edu/~zhuolin/projectlcksvd.html The source code for submodular reranking for retrieval is released now! [project page] One paper is accepted

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

#include <opencv2/opencv.hpp>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <iostream>using namespace std;using namespace cv;const int w = 384;const int h = 288;const int n = 3;void SAD(uchar* Limg,

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

主要内容: 1.MP算法 2.OMP算法 3.OMP算法的matlab实现 4.OMP在压缩感知和人脸识别的应用 一.MP(Matching Pursuits)与OMP(Orthogonal Matching Pursuit)算法 内容:稀疏信号的表示(字典.稀疏系数).MP算法.MP算法的缺点.OMP.OMP的实现 参考文章:http://blog.csdn.net/scucj/article/details/7467955 二.OMP的matlab实现 %A-稀疏系数矩阵%D-字典/测量矩阵

算法导论——所有点对最短路径:稀疏图Johnson算法

package org.loda.graph; import org.loda.structure.Stack; import org.loda.util.In; /** * * @ClassName: Johnson 时间复杂度:EVlgV * @Description: 稀疏图上的johnson算法,由于稀疏图的数据结构推荐使用邻接链表,所以这里也采用邻接链表,该算法也是给稀疏图使用的,如果是密集图,推荐使用实现较为简单的FloydWashall算法,可以保证V^3的时间复杂度 * * Jo

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

scikit-learn对于线性回归提供了比较多的类库,这些类库都可以用来做线性回归分析,本文就对这些类库的使用做一个总结,重点讲述这些线性回归算法库的不同和各自的使用场景. 线性回归的目的是要得到输出向量YY和输入特征XX之间的线性关系,求出线性回归系数θθ,也就是 Y=XθY=Xθ.其中YY的维度为mx1,XX的维度为mxn,而θθ的维度为nx1.m代表样本个数,n代表样本特征的维度. 为了得到线性回归系数θθ,我们需要定义一个损失函数,一个极小化损失函数的优化方法,以及一个验证算法的方法.

浅谈压缩感知(二十八):压缩感知重构算法之广义正交匹配追踪(gOMP)

主要内容: gOMP的算法流程 gOMP的MATLAB实现 一维信号的实验与结果 稀疏度K与重构成功概率关系的实验与结果 一.gOMP的算法流程 广义正交匹配追踪(Generalized OMP, gOMP)算法可以看作为OMP算法的一种推广.OMP每次只选择与残差相关最大的一个,而gOMP则是简单地选择最大的S个.之所以这里表述为"简单地选择"是相比于ROMP之类算法的,不进行任何其它处理,只是选择最大的S个而已. gOMP的算法流程: 二.gOMP的MATLAB实现(CS_gOMP

浅谈压缩感知(十九):MP、OMP与施密特正交化

关于MP.OMP的相关算法与收敛证明,可以参考:http://www.cnblogs.com/AndyJee/p/5047174.html,这里仅简单陈述算法流程及二者的不同之处. 主要内容: MP的算法流程及其MATLAB实现 OMP的算法流程以及MATLAB实现 MP与OMP的区别 施密特正交化与OMP的关系 一.MP(匹配追踪)的算法流程: 二.MP的MATLAB实现: % MP:匹配追踪算法 % dictionary: 超完备字典 % x: 待表示信号 % M = 4; N = 10;