├── cars.avi ├── README.md ├── coded_snapshot.m ├── OMP_reconstruct.m ├── omp_solve.m └── main.m /cars.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robodhruv/orthogonal-matching-pursuit/HEAD/cars.avi -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Orthogonal Matching Pursuit 2 | Dhruv Ilesh Shah and Tanya Choudhary 3 | 4 | This repository contains implementation of the orthogonal matching pursuit algorithm for the recovery of sparse (or compressible) signals, from their compressive measurements. The code in `main.m` replicates the recovery process for the video compressive sensing architecture proposed by Hitomi et al. in ICCV 2011. More information on the project [here](http://www.cs.columbia.edu/CAVE/projects/single_shot_video/). -------------------------------------------------------------------------------- /coded_snapshot.m: -------------------------------------------------------------------------------- 1 | function [ E_noisy, Ci,F ] = coded_snapshot( H,W,T,noiseMean,noiseSD) 2 | %Obtain coded snapshot with gaussian random noise 3 | 4 | V = mmread('../cars.avi',1:T); 5 | F = zeros(H,W,T); 6 | E = zeros(H,W); 7 | Ci = randi([0, 1], [H,W,T]); 8 | for i=1:T 9 | F(:,:,i) = double(rgb2gray(V.frames(i).cdata(288-H+1:288,352-W+1:352,:))); 10 | E = E + Ci(:,:,i).*F(:,:,i); 11 | end 12 | 13 | noise = noiseMean + noiseSD*randn(size(E)); 14 | E_noisy = E+ noise; 15 | figure;imshow(mat2gray(E_noisy)); 16 | end 17 | 18 | -------------------------------------------------------------------------------- /OMP_reconstruct.m: -------------------------------------------------------------------------------- 1 | function x = OMP_reconstruct( E_noisy,Ci,p,T,epsilon ) 2 | % function to reconstruct each patch with 2-DCT basis 3 | 4 | C = double(reshape(Ci,p*p,T)); 5 | y = double(E_noisy(:)); 6 | dct1dT = dctmtx(8)'; 7 | dct2dT = kron(dct1dT,dct1dT); 8 | A = zeros(p*p,p*p*T); 9 | for i=1:T 10 | A(:,(i-1)*p*p + 1 : i*p*p) = diag(C(:,i))*dct2dT; 11 | end 12 | theta = omp_solve(A,y,epsilon); 13 | theta = reshape(theta,[p*p T]); 14 | x = zeros(p*p,T); 15 | for i=1:T 16 | x(:,i) = dct2dT*theta(:,i); 17 | end 18 | x = reshape(x,[p p T]); 19 | end 20 | 21 | -------------------------------------------------------------------------------- /omp_solve.m: -------------------------------------------------------------------------------- 1 | function [theta,At] = omp_solve(A,y,epsilon) 2 | N = size(A,2); 3 | theta = zeros(N,1); 4 | y = y(:); 5 | r = y; 6 | Ti = []; 7 | 8 | % norm of each column 9 | norm_A = zeros(1,N); 10 | for j = 1:N 11 | norm_A(1,j) = norm(A(:,j),2); 12 | end 13 | 14 | while(norm(r) > epsilon) 15 | 16 | % Normalised correlation of each col of A with r 17 | aj = abs((r'*A) ./ norm_A); 18 | [ajmax, j] = max(aj); 19 | Ti = [Ti j]; 20 | At = A(:,Ti); 21 | s = (At' * At) \ At' * y; 22 | r = y - At*s; 23 | end 24 | 25 | theta(Ti) = s; 26 | end 27 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | %% Parameters 2 | H = 120; 3 | W = 240; 4 | Tlist = [3,5,7]; 5 | noiseMean = 0; 6 | noiseSD = 2; 7 | epsilon = 16; 8 | patch = 8; 9 | stride = 1; 10 | %% Reconstruction method 11 | % The matrix A for OMP is formed by aligning the code matrix along diagonal 12 | % of an HWxHW matrix for each frame. All the diagonal matrices are then 13 | % concatenated. [C1| C2| ..] 14 | % The vector b is constructed by vectorizing the noisy coded snapshot. 15 | relMseVall2 = zeros(length(Tlist),1); 16 | for Ti=1:length(Tlist) 17 | T = Tlist(Ti); 18 | [E_noisy,Ci,F] = coded_snapshot(H,W,T,noiseMean,noiseSD); 19 | 20 | x = zeros(H,W,T); 21 | h = H/stride - patch/stride +1; 22 | w = W/stride - patch/stride +1; 23 | normalization_mat = zeros(H,W); 24 | for i=1:h 25 | i_b = (i-1)*stride+1; 26 | for j=1:w 27 | j_b = (j-1)*stride+1; 28 | x(i_b:i_b+patch-1,j_b:j_b+patch-1,:)=x(i_b:i_b+patch-1,j_b:j_b+patch-1,:)... 29 | + OMP_reconstruct(E_noisy(i_b:i_b+patch-1,j_b:j_b+patch-1),Ci(i_b:i_b+patch-1,j_b:j_b+patch-1,:),patch,T,epsilon); 30 | normalization_mat(i_b:i_b+patch-1,j_b:j_b+patch-1) = normalization_mat(i_b:i_b+patch-1,j_b:j_b+patch-1)+1; 31 | end 32 | end 33 | relMseVall2_img=zeros(T, 1); 34 | for i=1:T 35 | x(:,:,i) = x(:,:,i)./normalization_mat; 36 | output = mat2gray([x(:,:,i) F(:,:,i)]); 37 | figure;imshow(output); 38 | fname=sprintf(strcat('output', num2str(i), num2str(T), '.png')); 39 | imwrite(output,fname,'PNG'); 40 | relMseVall2_img(i) = mean2((x(:,:,i)- F(:,:,i)).^2)/mean2(F(:,:,i).^2); 41 | end 42 | relMseVall2(Ti)=mean(relMseVall2_img); 43 | end 44 | relMseVall2 45 | %relative mean squared increases on increasing the number of frames --------------------------------------------------------------------------------