├── intro.pdf ├── notes on spi.pdf ├── HadamardMatrices.png ├── normalize_matrix.m ├── rmse.m ├── bin2dec0.m ├── Walsh_Hadamard_Transform.m ├── rperm.m ├── change_of_sign.m ├── Walsh_Paley_Transform.m ├── renameImages.m ├── Haar_Transform.m ├── Normalized_Haar_Transform.m ├── IndexingMatrix.m ├── Walsh_System_Transform.m ├── Cal_Sal_Transform.m ├── dspi.m ├── GCK.m ├── Cake_Cutting.m ├── LICENSE ├── dspi_differential.m ├── UpdateList.m ├── count_regions.m ├── zigzag.m ├── demo1.m ├── GCSS.m ├── README.md ├── demo3.m ├── ssim_index.m ├── demo2.m ├── demo4.m └── demo5.m /intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamdelacruz/Single-Pixel-Imaging/HEAD/intro.pdf -------------------------------------------------------------------------------- /notes on spi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamdelacruz/Single-Pixel-Imaging/HEAD/notes on spi.pdf -------------------------------------------------------------------------------- /HadamardMatrices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/williamdelacruz/Single-Pixel-Imaging/HEAD/HadamardMatrices.png -------------------------------------------------------------------------------- /normalize_matrix.m: -------------------------------------------------------------------------------- 1 | function [y] = normalize_matrix(im) 2 | min1 = min(im(:)); 3 | im = im - min1; 4 | max1 = max(im(:)); 5 | y = im / max1; -------------------------------------------------------------------------------- /rmse.m: -------------------------------------------------------------------------------- 1 | % Commpute the normalized RMSE 2 | function error = rmse(I1, I2) 3 | [ny, nx] = size(I1); 4 | diff = (I1(:)-I2(:)).^2; 5 | error = sqrt( sum(diff)/(ny*nx) ); 6 | end -------------------------------------------------------------------------------- /bin2dec0.m: -------------------------------------------------------------------------------- 1 | function dec = bin2dec0(list) 2 | % spin to binary 3 | list = (list + 1)/2; 4 | 5 | N = length(list); 6 | dec = 0; 7 | for j=1:N 8 | dec = dec + list(N-j+1)*2^(j-1); 9 | end 10 | -------------------------------------------------------------------------------- /Walsh_Hadamard_Transform.m: -------------------------------------------------------------------------------- 1 | function w = Walsh_Hadamard_Transform(n) 2 | % Walsh-Hadamard transform 3 | w = [1 1; 1 -1]; 4 | 5 | for N=1:n-1 6 | Wk = [w w; w -w]; 7 | w = Wk; 8 | end 9 | end -------------------------------------------------------------------------------- /rperm.m: -------------------------------------------------------------------------------- 1 | function perm=rperm(N) 2 | 3 | list=1:N; 4 | perm = zeros(1,N); 5 | 6 | for k=1:N 7 | x = randi(N-k+1); 8 | perm(k) = list(x); 9 | swap = list(N-k+1); 10 | list(N-k+1) = list(x); 11 | list(x) = swap; 12 | end -------------------------------------------------------------------------------- /change_of_sign.m: -------------------------------------------------------------------------------- 1 | function [sign] = change_of_sign(H) 2 | 3 | dim = size(H,1); 4 | sign = zeros(1,dim); 5 | 6 | for i=1:dim 7 | change = 0; 8 | for j=1:dim-1 9 | if H(i,j)~=H(i,j+1) 10 | change = change + 1; 11 | end 12 | end 13 | sign(i) = change; 14 | end -------------------------------------------------------------------------------- /Walsh_Paley_Transform.m: -------------------------------------------------------------------------------- 1 | function w = Walsh_Paley_Transform(n) 2 | % Walsh-Paley transform 3 | Pk = [1]; 4 | B1 = [1 1]; 5 | B2 = [1 -1]; 6 | 7 | for k=1:n 8 | pk1 = kron(Pk,B1); 9 | pk2 = kron(Pk,B2); 10 | Pk = [pk1; pk2]; 11 | end 12 | 13 | w = Pk; 14 | end -------------------------------------------------------------------------------- /renameImages.m: -------------------------------------------------------------------------------- 1 | % Re-nombra archivos 2 | db_path = '\coco-train2014\'; 3 | Files = dir('.\coco-train2014\*.jpg'); 4 | 5 | 6 | fprintf('Re-indexing %d images ...\n', length(Files)); 7 | 8 | for k=1:length(Files) 9 | FileNames = Files(k).name; 10 | old_name = strcat(path_dir,db_path,FileNames); 11 | name = strcat('COCO_train2014_', num2str(k), '.jpg'); 12 | new_name = strcat(path_dir,db_path,name); 13 | movefile(old_name, new_name) 14 | end 15 | 16 | fprintf('Finished\n'); 17 | -------------------------------------------------------------------------------- /Haar_Transform.m: -------------------------------------------------------------------------------- 1 | function w = Haar_Transform(n) 2 | % Walsh-Paley transform 3 | Haar = [1 1; 1 -1]; 4 | B1 = [1 1]; 5 | B2 = [1 -1]; 6 | 7 | if n==1 8 | w = Haar; 9 | else 10 | H = Haar; 11 | for k=2:n 12 | pk1 = kron(H, B1); 13 | In = eye(2^(k-1)); 14 | pk2 = kron(sqrt(2^(k-1))*In,B2); 15 | Pk = [pk1; pk2]; 16 | H = Pk; 17 | end 18 | 19 | w = H; 20 | end 21 | end -------------------------------------------------------------------------------- /Normalized_Haar_Transform.m: -------------------------------------------------------------------------------- 1 | function w = Normalized_Haar_Transform(n) 2 | % Walsh-Paley transform 3 | Haar = [1 1; 1 -1]; 4 | B1 = [1 1]; 5 | B2 = [1 -1]; 6 | 7 | if n==1 8 | w = Haar; 9 | else 10 | H = Haar; 11 | for k=2:n 12 | pk1 = kron(H, B1); 13 | In = eye(2^(k-1)); 14 | pk2 = kron(In,B2); 15 | Pk = [pk1; pk2]; 16 | H = Pk; 17 | end 18 | 19 | w = H; 20 | end 21 | end -------------------------------------------------------------------------------- /IndexingMatrix.m: -------------------------------------------------------------------------------- 1 | function Index = IndexingMatrix(H1, H, Len) 2 | Index = zeros(1,Len); 3 | 4 | for i=1:Len 5 | row1 = H(i,:); 6 | j=1; 7 | flag = 1; 8 | 9 | while j<=Len && flag==1 10 | row2 = H1(j,:); 11 | k=1; 12 | 13 | while k<=Len && row1(k)==row2(k) 14 | k=k+1; 15 | end 16 | 17 | if k>Len 18 | flag=0; 19 | end 20 | 21 | j=j+1; 22 | end 23 | 24 | Index(i)=j-1; 25 | end -------------------------------------------------------------------------------- /Walsh_System_Transform.m: -------------------------------------------------------------------------------- 1 | function w = Walsh_System_Transform(n) 2 | % Walsh-systems 3 | W2 = [1 1; 1 -1]; 4 | R = [0 1; 1 0]; 5 | 6 | if n==1 7 | w = W2; 8 | else 9 | A = W2; 10 | 11 | % construct recursively the matrix W 12 | for N=1:n-1 13 | Wk = zeros(2^(N+1), 2^(N+1)); 14 | % for each column of A 15 | k = 1; 16 | for i=1:2:2^N 17 | Wk(:,k:k+3) = [kron(W2,A(:,i)) kron(W2*R,A(:,i+1))]; 18 | k = k + 4; 19 | end 20 | 21 | A = Wk; 22 | end 23 | w = A; 24 | end 25 | end -------------------------------------------------------------------------------- /Cal_Sal_Transform.m: -------------------------------------------------------------------------------- 1 | function w = Cal_Sal_Transform(n) 2 | % Cal-Sal transform 3 | w = zeros(2^n, 2^n); 4 | R = zeros(n, n); 5 | 6 | if n==1 7 | R = [1]; 8 | else 9 | for k=1:n-1 10 | R(k,n-k+1) = 1; 11 | R(n-k+1,k+1) = 1; 12 | end 13 | R(n, 1) = 1; 14 | end 15 | 16 | for j=1:2^n 17 | bj = flip(de2bi(j-1,n)); 18 | w(j, j) = (-1)^sum(bj*R*bj'); 19 | 20 | for k=j+1:2^n 21 | bk = flip(de2bi(k-1,n)); 22 | entry = (-1)^sum(bj*R*bk'); 23 | w(j, k) = entry; 24 | w(k, j) = entry; 25 | end 26 | end 27 | end -------------------------------------------------------------------------------- /dspi.m: -------------------------------------------------------------------------------- 1 | function [target, target_noise] = dspi(H, sampledImg, snr, dim) 2 | % Single-Pixel image reconstruction 3 | 4 | % Positive Hadamard patterns 5 | H1 = (H+1)/2; 6 | 7 | % Negative Hadamard patterns 8 | H0 = (1-H)/2; 9 | 10 | % Generate simulated measurements using positive and negative patterns 11 | M1 = H1*sampledImg(:); 12 | M0 = H0*sampledImg(:); 13 | 14 | %Generate measurements corrupted by noise 15 | M1Noise = awgn(M1,snr,'measured'); 16 | M0Noise = awgn(M0,snr,'measured'); 17 | 18 | % Generate true Hadamard coefficients 19 | M = M1 - M0; 20 | MNoise = M1Noise - M0Noise; 21 | 22 | % Reconstruct object 23 | target = H\M; 24 | target = reshape(target,[2^dim 2^dim]); 25 | 26 | % Reconstruct object with noise 27 | target_noise = H\MNoise; 28 | target_noise = reshape(target_noise,[2^dim 2^dim]); 29 | end -------------------------------------------------------------------------------- /GCK.m: -------------------------------------------------------------------------------- 1 | % Construction of generalized Hadamard matrices 2 | % based on gray code sequence 3 | function [vs, sg] = GCK(n, s) 4 | vs = s; 5 | sg = []; 6 | 7 | for k=1:n 8 | M = size(vs,1); 9 | N = size(vs,2); 10 | vk = zeros(2*M, 2*N); 11 | % For the alpha-related property 12 | sign = zeros(2*M, k); 13 | 14 | i = 1; 15 | for j=1:2:2*M 16 | vk(j, :) = [ vs(i,:) vs(i,:)]; 17 | if isempty(sg) 18 | sign(j,:) = 1; 19 | else 20 | sign(j,:) = [sg(i,:) 1]; 21 | end 22 | 23 | vk(j+1, :) = [ vs(i,:) -vs(i,:)]; 24 | if isempty(sg) 25 | sign(j+1,:) = -1; 26 | else 27 | sign(j+1,:) = [sg(i,:) -1]; 28 | end 29 | 30 | i=i+1; 31 | end 32 | 33 | vs = vk; 34 | sg = sign; 35 | end 36 | end -------------------------------------------------------------------------------- /Cake_Cutting.m: -------------------------------------------------------------------------------- 1 | % Compute the cake cutting ordering of a Hadamard matix 2 | % The parameter type can be either 'blocks' or 'lblocks'. In the first 3 | % case, it obtaings an ordering based on the number of blocks, and in the 4 | % second case, it obtains an ordering based on the largest block size 5 | function [H_new, I, blocks] = Cake_Cutting(H, dim, type) 6 | 7 | len = 2^(2*dim); 8 | blocks = zeros(1,len); 9 | 10 | for ii=1:len 11 | p = reshape(H(ii,:), [2^dim 2^dim]); 12 | [b0, b1, lbs]=count_regions(p, 2^dim); 13 | if strcmp(type,'blocks') 14 | blocks(ii) = b0+b1; 15 | elseif strcmp(type,'lblocks') 16 | blocks(ii) = lbs; 17 | end 18 | end 19 | 20 | % sort from larger to lower number of blocks 21 | if strcmp(type,'blocks') 22 | [~, I] = sort(blocks,'ascend'); 23 | elseif strcmp(type,'lblocks') 24 | [~, I] = sort(blocks,'descend'); 25 | end 26 | 27 | H_new = zeros(size(H)); 28 | for i=1:size(H,1) 29 | H_new(i,:) = H(I(i), :); 30 | end -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 William De la Cruz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /dspi_differential.m: -------------------------------------------------------------------------------- 1 | % Single-Pixel image reconstruction 2 | 3 | function [target, target_noise] = dspi_differential(H, img, snr, dim, ... 4 | option_sampling, sampling_ratio) 5 | % Positive Hadamard patterns 6 | H1 = max(H, 0); 7 | 8 | % Negative Hadamard patterns 9 | H0 = abs(min(H, 0)); 10 | 11 | % Generate simulated measurements using positive and negative patterns 12 | M1 = H1*img(:); 13 | M0 = H0*img(:); 14 | 15 | %Generate measurements corrupted by noise 16 | M1Noise = awgn(M1,snr,'measured'); 17 | M0Noise = awgn(M0,snr,'measured'); 18 | 19 | % Generate true Hadamard coefficients 20 | M = M1 - M0; 21 | MNoise = M1Noise - M0Noise; 22 | 23 | % Apply sampling 24 | if option_sampling==1 25 | if sampling_ratio>0.0 && sampling_ratio<1.0 26 | l = round(length(M)*sampling_ratio); 27 | M(l: end) = 0; 28 | MNoise(l: end) = 0; 29 | end 30 | end 31 | 32 | % Reconstruct object without noise 33 | %target = H\M; 34 | target =(1/2^(2*dim))*H'*M; 35 | target = reshape(target,[2^dim 2^dim]); 36 | 37 | % Reconstruct object with noise 38 | %target_noise = H\MNoise; 39 | target_noise =(1/2^(2*dim))*H'*MNoise; 40 | target_noise = reshape(target_noise,[2^dim 2^dim]); 41 | end -------------------------------------------------------------------------------- /UpdateList.m: -------------------------------------------------------------------------------- 1 | function [B, bitflags, stack, index, block_size] = UpdateList(seed, B_ref, bitflags_ref, stack_ref, index_ref, y, x, block_size_ref) 2 | B = B_ref; 3 | bitflags = bitflags_ref; 4 | stack = stack_ref; 5 | index = index_ref; 6 | block_size = block_size_ref; 7 | 8 | [dimy, dimx] = size(B); 9 | 10 | if y-1>=1 11 | if bitflags(y-1, x)==0 && B(y-1,x)==seed 12 | index = index + 1; 13 | stack(index, :) = [y-1 x]; 14 | bitflags(y-1, x) = 1; 15 | block_size = block_size + 1; 16 | end 17 | end 18 | 19 | if y+1<=dimy 20 | if bitflags(y+1,x)==0 && B(y+1,x)==seed 21 | index = index + 1; 22 | stack(index, :) = [y+1 x]; 23 | bitflags(y+1, x) = 1; 24 | block_size = block_size + 1; 25 | end 26 | end 27 | 28 | if x-1>=1 29 | if bitflags(y,x-1)==0 && B(y,x-1)==seed 30 | index = index + 1; 31 | stack(index, :) = [y x-1]; 32 | bitflags(y, x-1) = 1; 33 | block_size = block_size + 1; 34 | end 35 | end 36 | 37 | if x+1<=dimx 38 | if bitflags(y,x+1)==0 && B(y,x+1)==seed 39 | index = index + 1; 40 | stack(index, :) = [y x+1]; 41 | bitflags(y, x+1) = 1; 42 | block_size = block_size + 1; 43 | end 44 | end -------------------------------------------------------------------------------- /count_regions.m: -------------------------------------------------------------------------------- 1 | % Count the number of connected regions in a binary image 2 | function [pieces_back, pieces_white, largest_block_size] = count_regions(B, n) 3 | bitflags = zeros(n, n); 4 | pieces_back = 0; 5 | pieces_white = 0; 6 | largest_block_size = 0; 7 | 8 | for i=1:n 9 | for j=1:n 10 | if bitflags(i,j)==0 11 | bitflags(i,j) = 1; 12 | stack = zeros(n*n,2); 13 | index = 0; 14 | seed = B(i,j); 15 | block_size = 1; 16 | 17 | if seed ==1 18 | pieces_white = pieces_white + 1; 19 | else 20 | pieces_back = pieces_back + 1; 21 | end 22 | 23 | [B, bitflags, stack, index, block_size] = UpdateList(seed, B, bitflags, stack, index, i, j, block_size); 24 | % fullfil of a region 25 | while index>0 26 | y = stack(index, 1); 27 | x = stack(index, 2); 28 | index = index - 1; 29 | [B, bitflags, stack, index, block_size] = UpdateList(seed, B, bitflags, stack, index, y, x, block_size); 30 | end 31 | 32 | if block_size > largest_block_size %&& seed==1 33 | largest_block_size = block_size; 34 | end 35 | end 36 | end 37 | end -------------------------------------------------------------------------------- /zigzag.m: -------------------------------------------------------------------------------- 1 | function sol = zigzag(H) 2 | 3 | [n, m] = size(H); 4 | sol = zeros(1,n*m); 5 | 6 | row = 0; 7 | col = 0; 8 | row_inc = 0; 9 | 10 | % Print matrix of lower half zig-zag pattern 11 | mn = min(m, n); 12 | 13 | iter = 1; 14 | 15 | for len=1:mn 16 | for i=0:len-1 17 | %fprintf('%d ',H(row+1,col+1)) 18 | sol(iter) = H(row+1,col+1); 19 | iter = iter+1; 20 | 21 | if (i+1)==len 22 | break 23 | end 24 | 25 | if row_inc 26 | row = row + 1; 27 | col = col - 1; 28 | else 29 | row = row - 1; 30 | col = col + 1; 31 | end 32 | end 33 | 34 | if len == mn 35 | break 36 | end 37 | 38 | if row_inc 39 | row = row + 1; 40 | row_inc = 0; 41 | else 42 | col = col + 1; 43 | row_inc = 1; 44 | end 45 | end 46 | 47 | 48 | 49 | % Update the indexes of row and col variable 50 | if (row == 0) 51 | if (col == m - 1) 52 | row = row+1; 53 | else 54 | col=col+1; 55 | end 56 | row_inc = 1; 57 | else 58 | if row == n - 1 59 | col = col+1; 60 | else 61 | row = row+1; 62 | end 63 | row_inc = 0; 64 | end 65 | 66 | % Print the next half zig-zag pattern 67 | MAX = max(m, n) - 1; 68 | 69 | for diag=MAX:-1:1 70 | if (diag > mn) 71 | len = mn; 72 | else 73 | len = diag; 74 | end 75 | 76 | for i=0:len-1 77 | %fprintf('%d ',H(row+1,col+1)) 78 | sol(iter) = H(row+1,col+1); 79 | iter = iter+1; 80 | 81 | if (i + 1 == len) 82 | break; 83 | end 84 | 85 | if (row_inc) 86 | row=row+1; 87 | col=col-1; 88 | else 89 | col=col+1; 90 | row=row-1; 91 | end 92 | end 93 | 94 | % Update the indexes of row and col variable 95 | if (row == 0 || col == m - 1) 96 | if (col == m - 1) 97 | row=row+1; 98 | else 99 | col=col+1; 100 | end 101 | row_inc = 1; 102 | else 103 | if (col == 0 || row == n - 1) 104 | if (row == n - 1) 105 | col=col+1; 106 | else 107 | row=row+1; 108 | end 109 | 110 | row_inc = 0; 111 | end 112 | end 113 | end 114 | -------------------------------------------------------------------------------- /demo1.m: -------------------------------------------------------------------------------- 1 | % Single-pixel imaging using Hadamard patterns as sensing basis 2 | % Example of single pixel imaging using taditional Hadamard matrices 3 | 4 | clc 5 | close all 6 | clearvars 7 | 8 | % Load object 9 | img = imread('.\misc\5.3.01.tiff'); 10 | 11 | % sub-sampled image 12 | % The size of the sampled image must be a power of 2 13 | sampledImg = double(img(1:16:end, 1:16:end)); % 64x64p 14 | sampledImg = sampledImg/max(max(sampledImg)); 15 | npixels = size(sampledImg,1); 16 | 17 | fprintf('Size of image: %d pixels\n',npixels) 18 | 19 | % - - - - - - - - - - - - - - - - - - 20 | % Generate measurement patterns 21 | % - - - - - - - - - - - - - - - - - - 22 | 23 | % compute transform matrix 24 | fprintf('Computing Hadamard matrices\n') 25 | type_matrix = 1; 26 | dim = 6; 27 | 28 | if 2^(2*dim) ~= npixels^2 29 | fprintf('Dimensions do not agree.\n'); 30 | return 31 | end 32 | 33 | switch type_matrix 34 | case 1 35 | % Compute the Walsh Hadamard transform 36 | Ht = Walsh_Hadamard_Transform(2*dim); 37 | case 2 38 | % Compute the Walsh-Paley transform 39 | Ht = Walsh_Paley_Transform(2*dim); 40 | case 3 41 | % Compute the Cal-Sal transform 42 | Ht = Cal_Sal_Transform(2*dim); 43 | case 4 44 | % Compute the Walsh-systems 45 | Ht = Walsh_System_Transform(2*dim); 46 | case 5 47 | % Compute the Haar transform 48 | Ht = Haar_Transform(2*dim); 49 | otherwise 50 | fprintf('Invalid option.\n') 51 | return 52 | end 53 | 54 | % visualize the Hadamard matrix 55 | figure(1), imshow(Ht) 56 | 57 | % - - - - - - - - - - - - - - - - - - 58 | % Reconstruct scene 59 | % - - - - - - - - - - - - - - - - - - 60 | snr = 35; 61 | numIter = 1; 62 | avg_error = 0; 63 | 64 | fprintf('Reconstructing image:\n') 65 | 66 | for iter=1:numIter 67 | [target, target_noise] = dspi(Ht, sampledImg, snr, dim); 68 | % Calculate the error of the reconstructed image with added noise 69 | error = rmse(sampledImg, target_noise); 70 | avg_error = avg_error + error; 71 | end 72 | 73 | avg_error = avg_error/numIter; 74 | fprintf('Average error = %f\n',avg_error) 75 | 76 | % - - - - - - - - - - - - - - - 77 | % Plot reconstructed image 78 | % - - - - - - - - - - - - - - - 79 | figure(2) 80 | subplot(1,3,1) 81 | imshow(sampledImg) 82 | title('Original') 83 | subplot(1,3,2) 84 | imshow(target) 85 | title('Reconstructed') 86 | subplot(1,3,3) 87 | imshow(target_noise) 88 | title('Reconstructed with noise') -------------------------------------------------------------------------------- /GCSS.m: -------------------------------------------------------------------------------- 1 | function Hnew = GCSS(dim, ordering) 2 | %% Construct Hadamard matrix with a unique binary string per row 3 | 4 | 5 | if rem(dim,2)~=0 6 | fprintf('Incorrect dimension for Hadamard generation!\n'); 7 | return 8 | end 9 | 10 | dim2 = dim/2; 11 | 12 | % create Hadamard matrix or order dim-1 13 | [H1, sg1] = GCK(dim2, 1); 14 | 15 | % temporal 16 | H2 = zeros(size(H1)); 17 | sg2 = zeros(size(sg1)); 18 | Len = size(H1,1); 19 | 20 | 21 | 22 | %% Different ordering 23 | 24 | if strcmp(ordering,'dyadic') 25 | % sort w.r.t. the change of sign 26 | v = change_of_sign(H1); 27 | [~,Index] = sort(v, 'ascend'); 28 | 29 | for k=1:Len 30 | H2(k,:) = H1(Index(k),:); 31 | sg2(k,:) = sg1(Index(k),:); 32 | end 33 | elseif strcmp(ordering,'GCK') 34 | H2 = H1; 35 | sg2 = sg1; 36 | elseif strcmp(ordering,'random') 37 | rng(1) 38 | rp = rperm(Len); 39 | for k=1:Len 40 | H2(k,:) = H1(rp(k),:); 41 | sg2(k,:) = sg1(rp(k),:); 42 | end 43 | elseif strcmp(ordering,'natural') 44 | H = Walsh_Hadamard_Transform(dim2); 45 | Index = IndexingMatrix(H1, H, Len); 46 | for k=1:Len 47 | H2(k,:) = H1(Index(k),:); 48 | sg2(k,:) = sg1(Index(k),:); 49 | end 50 | elseif strcmp(ordering,'Walsh-Paley') 51 | H = Walsh_Paley_Transform(dim2); 52 | Index = IndexingMatrix(H1, H, Len); 53 | for k=1:Len 54 | H2(k,:) = H1(Index(k),:); 55 | sg2(k,:) = sg1(Index(k),:); 56 | end 57 | elseif strcmp(ordering,'Cal-Sal') 58 | H = Cal_Sal_Transform(dim2); 59 | Index = IndexingMatrix(H1, H, Len); 60 | for k=1:Len 61 | H2(k,:) = H1(Index(k),:); 62 | sg2(k,:) = sg1(Index(k),:); 63 | end 64 | elseif strcmp(ordering,'Walsh-System') 65 | H = Walsh_System_Transform(dim2); 66 | Index = IndexingMatrix(H1, H, Len); 67 | for k=1:Len 68 | H2(k,:) = H1(Index(k),:); 69 | sg2(k,:) = sg1(Index(k),:); 70 | end 71 | elseif strcmp(ordering,'other') 72 | H = GCK_paths_optimalOrdering(dim2, 1.0); 73 | Index = IndexingMatrix(H1, H, Len); 74 | for k=1:Len 75 | H2(k,:) = H1(Index(k),:); 76 | sg2(k,:) = sg1(Index(k),:); 77 | end 78 | end 79 | 80 | 81 | 82 | 83 | 84 | 85 | %% Matrix representation of the Hadamard matrix of order dim 86 | 87 | M = zeros(Len, Len); 88 | 89 | for i=1:Len 90 | str1 = sg2(i,:); 91 | for j=1:Len 92 | str2 = sg2(j,:); 93 | M(i,j) = bin2dec0([str1 str2]); 94 | end 95 | end 96 | 97 | 98 | %% Reference Hadamard matrix 99 | [Hr, sgr] = GCK(dim, 1); 100 | sgr_dec = zeros(1,size(sgr,1)); 101 | 102 | for k=1:size(sgr,1) 103 | sgr_dec(k) = bin2dec0(sgr(k,:)); 104 | end 105 | 106 | 107 | 108 | 109 | %% Hadamard matrix traversal 110 | 111 | route = zigzag(M); 112 | 113 | 114 | 115 | %% New ordering 116 | Hnew = zeros(size(Hr)); 117 | 118 | for k=1:size(Hnew,1) 119 | id = find(sgr_dec==route(k)); 120 | Hnew(k,:) = Hr(id(1),:); 121 | end 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Single Pixel Imaging 2 | Sorting of the Hadamard basis for Single Pixel Imaging 3 | 4 | 5 | 6 | ![This is an image](/HadamardMatrices.png) 7 | 8 | 9 | 10 | This repository contains the source code of a sorting method of the Hadamard basis applied for single pixel imaging (SPI). The sorting method is based on generalized orthogonal basis vectors which can be represented as a two-dimensional structure of Hadamard patterns. By taken advantage of the energy concentration of the Hadamard patterns at the left upper corner of the 2D structure, it is used a zigzag traversal in order to sort the patterns in descending order of importance. The obtained ordering of the patterns, within the framework of SPI, allows to reconstruct a given target image using a small number of patterns. 11 | 12 | The source code was written in Matlab on Windows operating system. 13 | 14 | 15 | For an introduction to single pixel imaging see the documents [intro1](https://github.com/williamdelacruz/Single-Pixel-Imaging/blob/master/intro.pdf) [intro 2](https://github.com/williamdelacruz/Single-Pixel-Imaging/blob/master/notes%20on%20spi.pdf) 16 | 17 | This repository contains the following folders and files: 18 | 19 | ## Structure 20 | Files and folders: 21 | - \TVAL3_beta2.4 22 | - \coco-train2014 23 | - \misc 24 | - \data 25 | - demo1.m 26 | - demo2.m 27 | - ... 28 | 29 | ## Configuration and data request 30 | 31 | Initially, the folders \coco-train2014 and \misc are empty since it requires externals image reporsitories which can be downloaded by permission of the creators. 32 | 33 | ### Image Databases 34 | Link to the images: 35 | * [COCO dataset] (http://images.cocodataset.org/zips/train2014.zip) 36 | * [The USC-SIPI Image Database] (https://sipi.usc.edu/database/misc.zip) 37 | 38 | Please note that the previous links to the datasets might change with time, it is advisable to visit the web page of the providers, namely, https://cocodataset.org/ and 39 | https://sipi.usc.edu/database/. Once the .zip files have been downloaded, they must be uncompressed into the main directory, replacing the existing folders. 40 | 41 | 42 | 43 | ### TVL3 Package 44 | Link to the tool: 45 | * [TVL3] (https://github.com/liuyang12/3DCS.git) 46 | 47 | In the previous link, go to packages and download the folder \TVL3_beta2.4, then move it to the main directory. 48 | 49 | ### \data folder 50 | 51 | This folder can be used to save precalculated Hadamard matrices. This is convenient when the dimension of the Hadamard matrix is greater than 2^7, which is time consuming to compute. 52 | 53 | 54 | ## Simulation and execution 55 | 56 | To test the Matlab library, run the `demo1.m`, `demo2.m`, `demo3.m`, `demo4.m`, or `demo5.m` script. 57 | 58 | 59 | _Important:_ 60 | - `demo4.m` and `demo5.m` require to rename the images of the COCO database before their execution. So, please, into the command prompt of the Matlab environment, type the script `renameImages` and wait until finished. 61 | - `demo4.m` and `demo5.m` require the `ssim` function for computing the Optimized Structural Similarity Index between two images. Matlab supports an implementation of the `ssim` function since R2014a into the Image Processing Toolbox. An existing implementation can be obtained from the following link [The SSIM Index for Image Quality Assessment](https://ece.uwaterloo.ca/~z70wang/research/ssim/). It was originally proposed in Z. Wang, A. C. Bovik, H. R. Sheikh and E. P. Simoncelli, "[Image quality assessment: From error visibility to structural similarity](https://doi.org/10.1109/TIP.2003.819861)," IEEE Transactions on Image Processing, vol. 13, no. 4, pp. 600-612, Apr. 2004. 62 | - If the provided repository is helpful for your research, please cite the following paper: 63 | [Lourdes López-García, William Cruz-Santos, Anmi García-Arellano, Pedro Filio-Aguilar, José A. Cisneros-Martínez, and Rubén Ramos-García, "Efficient ordering of the Hadamard basis for single pixel imaging," Opt. Express 30, 13714-13732 (2022)](https://doi.org/10.1364/OE.451656) 64 | 65 | 66 | _Related references_ 67 | 68 | - Donoho, D.L. (2006), For most large underdetermined systems of linear equations the minimal 𝓁1-norm solution is also the sparsest solution. Comm. Pure Appl. Math., 59: 797-829. https://doi.org/10.1002/cpa.20132 69 | - Candes, E., Romberg, J. Quantitative Robust Uncertainty Principles and Optimally Sparse Decompositions. Found Comput Math 6, 227–254 (2006). https://doi.org/10.1007/s10208-004-0162-x 70 | - Candès, Emmanuel & Romberg, Justin & Tao, Terence. (2006). Robust Uncertainty Principles : Exact Signal Frequency Information. Information Theory, IEEE Transactions on. 52. 489-509. https://doi.org/10.1109/TIT.2005.862083 71 | 72 | -------------------------------------------------------------------------------- /demo3.m: -------------------------------------------------------------------------------- 1 | % Single-pixel imaging using Hadamard patterns as sensing basis 2 | % A comparison of several permutations with the ordering GCSS 3 | clc 4 | close all 5 | clear 6 | 7 | % Load object 8 | img = imread('.\misc\4.1.01.tiff'); 9 | 10 | if size(img,3)==3 11 | img = rgb2gray(img); 12 | end 13 | 14 | dim = 6; 15 | size_img = 2^dim; 16 | 17 | 18 | % sub-sampled image 19 | % The size of the sampled image must be a power of 2 20 | img = double(imresize(img, [size_img size_img], 'bilinear')); 21 | img = img/max(max(img)); 22 | npixels = size(img,1); 23 | 24 | fprintf('Size of image: %d pixels\n',npixels) 25 | 26 | % - - - - - - - - - - - - - - - - - - 27 | % Generate measurement patterns 28 | % - - - - - - - - - - - - - - - - - - 29 | 30 | 31 | if 2^(2*dim) ~= npixels^2 32 | fprintf('Dimensions do not agree.\n'); 33 | return 34 | end 35 | 36 | 37 | % - - - - - - - - - - - - - - - - - - 38 | % Constructing Hadamard matrices 39 | % - - - - - - - - - - - - - - - - - - 40 | 41 | fprintf('Constructing Hadamard matrices.\n') 42 | 43 | H1 = GCSS(2*dim, 'Cal-Sal'); 44 | H2 = GCSS(2*dim, 'natural'); 45 | H3 = GCSS(2*dim, 'random'); 46 | H4 = GCSS(2*dim, 'Walsh-Paley'); 47 | H5 = GCSS(2*dim, 'dyadic'); 48 | 49 | 50 | 51 | 52 | % - - - - - - - - - - - - - - - - - - 53 | % Main program for simulation 54 | % - - - - - - - - - - - - - - - - - - 55 | 56 | snr = 40; 57 | option_sampling = 1; 58 | list_rmse = zeros(10,5); 59 | list_rmse_noise = zeros(10,5); 60 | list_images = {}; 61 | iter = 1; 62 | 63 | % storage for images 64 | img_nonoise = zeros(size_img, size_img, 10, 5); 65 | img_noise = zeros(size_img, size_img, 10, 5); 66 | 67 | fprintf('Simulation ...\n'); 68 | 69 | for sampling_ratio=0.1:0.1:1 70 | fprintf('Sampling ratio: %.2f\n',sampling_ratio*100); 71 | 72 | % Cal-Sal ordering 73 | [target, target_noise] = dspi_differential(H1, img, snr, dim, option_sampling, sampling_ratio); 74 | list_rmse(iter,1) = rmse(img, target); 75 | list_rmse_noise(iter,1) = rmse(img, target_noise); 76 | img_nonoise(:,:,iter, 1) = target; 77 | img_noise(:,:,iter, 1) = target_noise; 78 | 79 | % Natural ordering 80 | [target, target_noise] = dspi_differential(H2, img, snr, dim, option_sampling, sampling_ratio); 81 | list_rmse(iter,2) = rmse(img, target); 82 | list_rmse_noise(iter,2) = rmse(img, target_noise); 83 | img_nonoise(:,:,iter, 2) = target; 84 | img_noise(:,:,iter, 2) = target_noise; 85 | 86 | % Random ordering 87 | [target, target_noise] = dspi_differential(H3, img, snr, dim, option_sampling, sampling_ratio); 88 | list_rmse(iter,3) = rmse(img, target); 89 | list_rmse_noise(iter,3) = rmse(img, target_noise); 90 | img_nonoise(:,:,iter, 3) = target; 91 | img_noise(:,:,iter, 3) = target_noise; 92 | 93 | 94 | % Walsh Paley 95 | [target, target_noise] = dspi_differential(H4, img, snr, dim, option_sampling, sampling_ratio); 96 | list_rmse(iter,4) = rmse(img, target); 97 | list_rmse_noise(iter,4) = rmse(img, target_noise); 98 | img_nonoise(:,:,iter, 4) = target; 99 | img_noise(:,:,iter, 4) = target_noise; 100 | 101 | % Dyadic ordering 102 | [target, target_noise] = dspi_differential(H5, img, snr, dim, option_sampling, sampling_ratio); 103 | list_rmse(iter,5) = rmse(img, target); 104 | list_rmse_noise(iter,5) = rmse(img, target_noise); 105 | img_nonoise(:,:,iter, 5) = target; 106 | img_noise(:,:,iter, 5) = target_noise; 107 | 108 | iter = iter + 1; 109 | end 110 | 111 | 112 | % Plot the rmse for several Hadamard matrices with a sampling ratio 113 | range = (0.1:0.1:1)*100; 114 | 115 | figure(1) 116 | hold on, plot(range, list_rmse(:,1),'d-','LineWidth',1) 117 | hold on, plot(range, list_rmse(:,2),'o--','LineWidth',1) 118 | hold on, plot(range, list_rmse(:,3),'v-.','LineWidth',1) 119 | hold on, plot(range, list_rmse(:,4),'*:','LineWidth',1) 120 | hold on, plot(range, list_rmse(:,5),'p-','LineWidth',1) 121 | 122 | 123 | legend('Cal-Sal','Natural','Random','Walsh-Paley','Sequency (GCS+S)') 124 | xlabel('Sampling ratio (%)'); 125 | ylabel('RMSE') 126 | axis tight 127 | grid 128 | box on 129 | 130 | 131 | figure(2) 132 | hold on, plot(range, list_rmse_noise(:,1),'d-r') 133 | hold on, plot(range, list_rmse_noise(:,2),'o--b') 134 | hold on, plot(range, list_rmse_noise(:,3),'v-.k') 135 | hold on, plot(range, list_rmse_noise(:,4),'*:k') 136 | hold on, plot(range, list_rmse_noise(:,5),'p-k') 137 | legend('Cal-Sal','Natural','Random','Walsh-Paley','Sequency (GCS+S)') 138 | xlabel('Sampling ratio (%)'); 139 | ylabel('RMSE') 140 | title('Signal corrupted by noise') 141 | axis tight 142 | grid 143 | box on 144 | 145 | 146 | -------------------------------------------------------------------------------- /ssim_index.m: -------------------------------------------------------------------------------- 1 | function [mssim, ssim_map] = ssim_index(img1, img2, K, window, L) 2 | 3 | % ======================================================================== 4 | % SSIM Index with automatic downsampling, Version 1.0 5 | % Copyright(c) 2009 Zhou Wang 6 | % All Rights Reserved. 7 | % 8 | % ---------------------------------------------------------------------- 9 | % Permission to use, copy, or modify this software and its documentation 10 | % for educational and research purposes only and without fee is hereby 11 | % granted, provided that this copyright notice and the original authors' 12 | % names appear on all copies and supporting documentation. This program 13 | % shall not be used, rewritten, or adapted as the basis of a commercial 14 | % software or hardware product without first obtaining permission of the 15 | % authors. The authors make no representations about the suitability of 16 | % this software for any purpose. It is provided "as is" without express 17 | % or implied warranty. 18 | %---------------------------------------------------------------------- 19 | % 20 | % This is an implementation of the algorithm for calculating the 21 | % Structural SIMilarity (SSIM) index between two images 22 | % 23 | % Please refer to the following paper and the website with suggested usage 24 | % 25 | % Z. Wang, A. C. Bovik, H. R. Sheikh, and E. P. Simoncelli, "Image 26 | % quality assessment: From error visibility to structural similarity," 27 | % IEEE Transactios on Image Processing, vol. 13, no. 4, pp. 600-612, 28 | % Apr. 2004. 29 | % 30 | % http://www.ece.uwaterloo.ca/~z70wang/research/ssim/ 31 | % 32 | % Note: This program is different from ssim_index.m, where no automatic 33 | % downsampling is performed. (downsampling was done in the above paper 34 | % and was described as suggested usage in the above website.) 35 | % 36 | % Kindly report any suggestions or corrections to zhouwang@ieee.org 37 | % 38 | %---------------------------------------------------------------------- 39 | % 40 | %Input : (1) img1: the first image being compared 41 | % (2) img2: the second image being compared 42 | % (3) K: constants in the SSIM index formula (see the above 43 | % reference). defualt value: K = [0.01 0.03] 44 | % (4) window: local window for statistics (see the above 45 | % reference). default widnow is Gaussian given by 46 | % window = fspecial('gaussian', 11, 1.5); 47 | % (5) L: dynamic range of the images. default: L = 255 48 | % 49 | %Output: (1) mssim: the mean SSIM index value between 2 images. 50 | % If one of the images being compared is regarded as 51 | % perfect quality, then mssim can be considered as the 52 | % quality measure of the other image. 53 | % If img1 = img2, then mssim = 1. 54 | % (2) ssim_map: the SSIM index map of the test image. The map 55 | % has a smaller size than the input images. The actual size 56 | % depends on the window size and the downsampling factor. 57 | % 58 | %Basic Usage: 59 | % Given 2 test images img1 and img2, whose dynamic range is 0-255 60 | % 61 | % [mssim, ssim_map] = ssim(img1, img2); 62 | % 63 | %Advanced Usage: 64 | % User defined parameters. For example 65 | % 66 | % K = [0.05 0.05]; 67 | % window = ones(8); 68 | % L = 100; 69 | % [mssim, ssim_map] = ssim(img1, img2, K, window, L); 70 | % 71 | %Visualize the results: 72 | % 73 | % mssim %Gives the mssim value 74 | % imshow(max(0, ssim_map).^4) %Shows the SSIM index map 75 | %======================================================================== 76 | 77 | 78 | if (nargin < 2 || nargin > 5) 79 | mssim = -Inf; 80 | ssim_map = -Inf; 81 | return; 82 | end 83 | 84 | if (size(img1) ~= size(img2)) 85 | mssim = -Inf; 86 | ssim_map = -Inf; 87 | return; 88 | end 89 | 90 | [M N] = size(img1); 91 | 92 | if (nargin == 2) 93 | if ((M < 11) || (N < 11)) 94 | mssim = -Inf; 95 | ssim_map = -Inf; 96 | return 97 | end 98 | window = fspecial('gaussian', 11, 1.5); % 99 | K(1) = 0.01; % default settings 100 | K(2) = 0.03; % 101 | L = 255; % 102 | end 103 | 104 | if (nargin == 3) 105 | if ((M < 11) || (N < 11)) 106 | mssim = -Inf; 107 | ssim_map = -Inf; 108 | return 109 | end 110 | window = fspecial('gaussian', 11, 1.5); 111 | L = 255; 112 | if (length(K) == 2) 113 | if (K(1) < 0 || K(2) < 0) 114 | mssim = -Inf; 115 | ssim_map = -Inf; 116 | return; 117 | end 118 | else 119 | mssim = -Inf; 120 | ssim_map = -Inf; 121 | return; 122 | end 123 | end 124 | 125 | if (nargin == 4) 126 | [H W] = size(window); 127 | if ((H*W) < 4 || (H > M) || (W > N)) 128 | mssim = -Inf; 129 | ssim_map = -Inf; 130 | return 131 | end 132 | L = 255; 133 | if (length(K) == 2) 134 | if (K(1) < 0 || K(2) < 0) 135 | mssim = -Inf; 136 | ssim_map = -Inf; 137 | return; 138 | end 139 | else 140 | mssim = -Inf; 141 | ssim_map = -Inf; 142 | return; 143 | end 144 | end 145 | 146 | if (nargin == 5) 147 | [H W] = size(window); 148 | if ((H*W) < 4 || (H > M) || (W > N)) 149 | mssim = -Inf; 150 | ssim_map = -Inf; 151 | return 152 | end 153 | if (length(K) == 2) 154 | if (K(1) < 0 || K(2) < 0) 155 | mssim = -Inf; 156 | ssim_map = -Inf; 157 | return; 158 | end 159 | else 160 | mssim = -Inf; 161 | ssim_map = -Inf; 162 | return; 163 | end 164 | end 165 | 166 | 167 | img1 = double(img1); 168 | img2 = double(img2); 169 | 170 | % automatic downsampling 171 | f = max(1,round(min(M,N)/256)); 172 | %downsampling by f 173 | %use a simple low-pass filter 174 | if(f>1) 175 | lpf = ones(f,f); 176 | lpf = lpf/sum(lpf(:)); 177 | img1 = imfilter(img1,lpf,'symmetric','same'); 178 | img2 = imfilter(img2,lpf,'symmetric','same'); 179 | 180 | img1 = img1(1:f:end,1:f:end); 181 | img2 = img2(1:f:end,1:f:end); 182 | end 183 | 184 | C1 = (K(1)*L)^2; 185 | C2 = (K(2)*L)^2; 186 | window = window/sum(sum(window)); 187 | 188 | mu1 = filter2(window, img1, 'valid'); 189 | mu2 = filter2(window, img2, 'valid'); 190 | mu1_sq = mu1.*mu1; 191 | mu2_sq = mu2.*mu2; 192 | mu1_mu2 = mu1.*mu2; 193 | sigma1_sq = filter2(window, img1.*img1, 'valid') - mu1_sq; 194 | sigma2_sq = filter2(window, img2.*img2, 'valid') - mu2_sq; 195 | sigma12 = filter2(window, img1.*img2, 'valid') - mu1_mu2; 196 | 197 | if (C1 > 0 && C2 > 0) 198 | ssim_map = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))./((mu1_sq + mu2_sq + C1).*(sigma1_sq + sigma2_sq + C2)); 199 | else 200 | numerator1 = 2*mu1_mu2 + C1; 201 | numerator2 = 2*sigma12 + C2; 202 | denominator1 = mu1_sq + mu2_sq + C1; 203 | denominator2 = sigma1_sq + sigma2_sq + C2; 204 | ssim_map = ones(size(mu1)); 205 | index = (denominator1.*denominator2 > 0); 206 | ssim_map(index) = (numerator1(index).*numerator2(index))./(denominator1(index).*denominator2(index)); 207 | index = (denominator1 ~= 0) & (denominator2 == 0); 208 | ssim_map(index) = numerator1(index)./denominator1(index); 209 | end 210 | 211 | mssim = mean2(ssim_map); 212 | 213 | return -------------------------------------------------------------------------------- /demo2.m: -------------------------------------------------------------------------------- 1 | % Demo 2: 2 | % Image reconstruction using Single Pixel Imaging. We use several 3 | % sensing matrices: 4 | % 1) Walsh Hadamard Transform 5 | % 2) Walsh Paley Transform 6 | % 3) Cal Sal Transform 7 | % 4) Walsh System Transform 8 | % 5) Normalized Haar Transform 9 | % 6) Cake_Cutting, sort with respect to the number of blocks 10 | % 7) Cake_Cutting, sort with respect to the largest block per pattern 11 | % 8) GCSS with sequency permutation 12 | % 13 | % Single-pixel imaging using Hadamard patterns as sensing basis 14 | clc 15 | close all 16 | clear 17 | 18 | % Load object 19 | img = imread('.\misc\5.3.01.tiff'); 20 | 21 | if size(img,3)==3 22 | img = rgb2gray(img); 23 | end 24 | 25 | num_pixels = 64; 26 | 27 | % sub-sampled image 28 | % The size of the sampled image must be a power of 2 29 | img = double(imresize(img, [num_pixels num_pixels], 'bilinear')); 30 | img = img/max(max(img)); 31 | npixels = size(img,1); 32 | 33 | fprintf('Size of image: %d pixels\n',npixels) 34 | 35 | % - - - - - - - - - - - - - - - - - - 36 | % Generate measurement patterns 37 | % - - - - - - - - - - - - - - - - - - 38 | dim = 6; 39 | 40 | if 2^(2*dim) ~= npixels^2 41 | fprintf('Dimensions do not agree.\n'); 42 | return 43 | end 44 | 45 | 46 | % - - - - - - - - - - - - - - - - - - 47 | % Constructing Hadamard matrices 48 | % - - - - - - - - - - - - - - - - - - 49 | 50 | fprintf('Constructing Hadamard matrices.\n') 51 | 52 | 53 | H1 = Walsh_Hadamard_Transform(2*dim); 54 | H2 = Walsh_Paley_Transform(2*dim); 55 | H3 = Walsh_System_Transform(2*dim); 56 | 57 | if isfile('data/cakecutting64_blocks.mat')==1 58 | load 'data/cakecutting64_blocks.mat' 59 | else 60 | [H, ~, ~] = Cake_Cutting(H1, dim, 'blocks'); 61 | end 62 | H4 = H; 63 | 64 | H5 = GCSS(dim*2, 'dyadic'); 65 | 66 | 67 | 68 | % - - - - - - - - - - - - - - - - - - - - - - - - 69 | % Plot the sequency of each Hadamard matrix 70 | % - - - - - - - - - - - - - - - - - - - - - - - - 71 | figure(1) 72 | 73 | % Compute the Walsh Hadamard transform 74 | v = change_of_sign(H1); 75 | subplot(2,3,1) 76 | scatter(1:length(v),v,10,v,'s','filled') 77 | title('Walsh Hadamard') 78 | xlabel('Number of row') 79 | ylabel('Sequency number') 80 | axis tight 81 | grid 82 | 83 | % Compute the Walsh-Paley transform 84 | v = change_of_sign(H2); 85 | subplot(2,3,2) 86 | scatter(1:length(v),v,10,v,'s','filled') 87 | title('Walsh-Paley') 88 | xlabel('Number of row') 89 | ylabel('Sequency number') 90 | axis tight 91 | grid 92 | 93 | 94 | 95 | % Compute the Walsh-systems 96 | v = change_of_sign(H3); 97 | subplot(2,3,3) 98 | scatter(1:length(v),v,10,v,'s','filled') 99 | title('Walsh-systems') 100 | xlabel('Number of row') 101 | ylabel('Sequency number') 102 | axis tight 103 | grid 104 | 105 | 106 | 107 | % Cake cutting ordering blocks 108 | v = change_of_sign(H4); 109 | subplot(2,3,4) 110 | scatter(1:length(v),v,10,v,'s','filled') 111 | title('Cake cutting blocks') 112 | xlabel('Number of row') 113 | ylabel('Sequency number') 114 | axis tight 115 | grid 116 | 117 | 118 | % GCSS ordering 119 | v = change_of_sign(H5); 120 | subplot(2,3,5) 121 | scatter(1:length(v),v,10,v,'s','filled') 122 | title('GCS ordering') 123 | xlabel('Number of row') 124 | ylabel('Sequency number') 125 | axis tight 126 | grid 127 | 128 | 129 | 130 | % - - - - - - - - - - - - - - - - - - 131 | % Main program for simulation 132 | % - - - - - - - - - - - - - - - - - - 133 | 134 | snr = 50; 135 | option_sampling = 1; 136 | list_rmse = zeros(10,5); 137 | list_rmse_noise = zeros(10,5); 138 | list_images = {}; 139 | iter = 1; 140 | 141 | % storage for images 142 | img_nonoise = zeros(num_pixels, num_pixels, 10, 5); 143 | img_noise = zeros(num_pixels, num_pixels, 10, 5); 144 | 145 | fprintf('Simulation ...\n'); 146 | 147 | for sampling_ratio=0.1:0.1:1 148 | fprintf('Sampling ratio: %.2f\n',sampling_ratio*100); 149 | 150 | % Compute the Walsh Hadamard transform 151 | [target, target_noise] = dspi_differential(H1, img, snr, dim, option_sampling, sampling_ratio); 152 | list_rmse(iter,1) = rmse(img, target); 153 | list_rmse_noise(iter,1) = rmse(img, target_noise); 154 | img_nonoise(:,:,iter, 1) = target; 155 | img_noise(:,:,iter, 1) = target_noise; 156 | 157 | % Compute the Walsh-Paley transform 158 | [target, target_noise] = dspi_differential(H2, img, snr, dim, option_sampling, sampling_ratio); 159 | list_rmse(iter,2) = rmse(img, target); 160 | list_rmse_noise(iter,2) = rmse(img, target_noise); 161 | img_nonoise(:,:,iter, 2) = target; 162 | img_noise(:,:,iter, 2) = target_noise; 163 | 164 | 165 | % Compute the Walsh-systems 166 | [target, target_noise] = dspi_differential(H3, img, snr, dim, option_sampling, sampling_ratio); 167 | list_rmse(iter,3) = rmse(img, target); 168 | list_rmse_noise(iter,3) = rmse(img, target_noise); 169 | img_nonoise(:,:,iter, 3) = target; 170 | img_noise(:,:,iter, 3) = target_noise; 171 | 172 | 173 | % cake cutting blocks 174 | [target, target_noise] = dspi_differential(H4, img, snr, dim, option_sampling, sampling_ratio); 175 | list_rmse(iter,4) = rmse(img, target); 176 | list_rmse_noise(iter,4) = rmse(img, target_noise); 177 | img_nonoise(:,:,iter, 4) = target; 178 | img_noise(:,:,iter, 4) = target_noise; 179 | 180 | 181 | % GCS ordering 182 | [target, target_noise] = dspi_differential(H5, img, snr, dim, option_sampling, sampling_ratio); 183 | list_rmse(iter,5) = rmse(img, target); 184 | list_rmse_noise(iter,5) = rmse(img, target_noise); 185 | img_nonoise(:,:,iter, 5) = target; 186 | img_noise(:,:,iter, 5) = target_noise; 187 | 188 | iter = iter + 1; 189 | end 190 | 191 | 192 | % Plot the rmse for several Hadamard matrices with a sampling ratio 193 | range = 0.1:0.1:1; 194 | 195 | figure(2) 196 | hold on, plot(range, list_rmse(:,1),'d-') 197 | hold on, plot(range, list_rmse(:,2),'o-') 198 | hold on, plot(range, list_rmse(:,3),'s-') 199 | hold on, plot(range, list_rmse(:,4),'*-') 200 | hold on, plot(range, list_rmse(:,5),'p-') 201 | legend('Natural','Walsh-Paley','Walsh-systems','Cakecutting','GCS+S') 202 | 203 | xlabel('Sampling ratio (%)'); 204 | ylabel('RMSE') 205 | axis tight 206 | grid 207 | 208 | figure(3) 209 | hold on, plot(range, list_rmse_noise(:,1),'d-') 210 | hold on, plot(range, list_rmse_noise(:,2),'o-') 211 | hold on, plot(range, list_rmse_noise(:,3),'s-') 212 | hold on, plot(range, list_rmse_noise(:,4),'*-') 213 | hold on, plot(range, list_rmse_noise(:,5),'p-') 214 | legend('Natural','Walsh-Paley','Walsh-systems','Cakecutting','GCS+S') 215 | xlabel('Sampling ratio (%)'); 216 | ylabel('RMSE') 217 | title('Signal corrupted by noise') 218 | axis tight 219 | grid 220 | 221 | 222 | 223 | % - - - - - - - - - - - - - - - - - - - - - - - - 224 | % Plot reconstructed images 225 | % - - - - - - - - - - - - - - - - - - - - - - - - 226 | 227 | figure(4) 228 | title('Reconstructed images') 229 | index = 1; 230 | for j=1:10 231 | for k=1:5 232 | subplot(10,5,index) 233 | imshow(img_nonoise(:,:,j,k), [],'InitialMagnification',500) 234 | set(gca,'xtick',[],'ytick',[]) 235 | index = index + 1; 236 | end 237 | end 238 | 239 | figure(5) 240 | title('Reconstructed images with noise') 241 | index = 1; 242 | for j=1:10 243 | for k=1:5 244 | subplot(10,5,index) 245 | imshow(img_nonoise(:,:,j,k),[],'InitialMagnification',500) 246 | set(gca,'xtick',[],'ytick',[]) 247 | index = index + 1; 248 | end 249 | end -------------------------------------------------------------------------------- /demo4.m: -------------------------------------------------------------------------------- 1 | % Comparison of the matrix ordering Cake Cutting and GCS+S 2 | % Using the COCO database 3 | % 4 | 5 | clc 6 | close all 7 | clear 8 | 9 | 10 | % - - - - - - - - - - - - - - - - - - 11 | % Generate measurement patterns 12 | % - - - - - - - - - - - - - - - - - - 13 | dim = 6; 14 | size_img = 2^dim; 15 | 16 | % - - - - - - - - - - - - - - - - - - 17 | % Constructing Hadamard matrices 18 | % - - - - - - - - - - - - - - - - - - 19 | 20 | fprintf('Constructing Hadamard matrices.\n') 21 | 22 | 23 | H1 = Walsh_Hadamard_Transform(2*dim); 24 | H2 = Walsh_Paley_Transform(2*dim); 25 | H3 = Walsh_System_Transform(2*dim); 26 | 27 | if isfile('data/cakecutting128_blocks.mat')==1 28 | load 'data/cakecutting128_blocks.mat' 29 | else 30 | [H, ~, ~] = Cake_Cutting(H1, dim, 'blocks'); 31 | end 32 | H4 = H; 33 | 34 | H5 = GCSS(2*dim, 'dyadic'); 35 | 36 | 37 | 38 | % - - - - - - - - - - - - - - - - - - 39 | % Main program for simulation 40 | % - - - - - - - - - - - - - - - - - - 41 | 42 | num_images = 10; 43 | 44 | sampling_list = [0.05 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0]; 45 | len_sl = length(sampling_list); 46 | 47 | snr = 50; 48 | 49 | option_sampling = 1; 50 | list_rmse = zeros(len_sl, 5, num_images); 51 | list_rmse_noise = zeros(len_sl, 5, num_images); 52 | list_ssim = zeros(len_sl, 5, num_images); 53 | list_ssim_noise = zeros(len_sl, 5, num_images); 54 | list_images = zeros(1, num_images); 55 | 56 | % storage for images 57 | img_nonoise = zeros(size_img, size_img, len_sl, 5, num_images); 58 | img_noise = zeros(size_img, size_img, len_sl, 5, num_images); 59 | 60 | 61 | fprintf('Simulation ...\n'); 62 | 63 | 64 | for im=1:num_images 65 | % Load a random object 66 | index_img = randi(82783); 67 | list_images(im) = index_img; 68 | name = strcat('COCO_train2014_', num2str(index_img), '.jpg'); 69 | path_img = strcat('.\coco-train2014\', name); 70 | img = imread(path_img); 71 | fprintf('Image: %s\n', path_img); 72 | 73 | if size(img,3)==3 74 | img = rgb2gray(img); 75 | end 76 | 77 | % sub-sampled image 78 | img = double(imresize(img, [size_img size_img], 'bilinear')); 79 | img = img/max(max(img)); 80 | 81 | iter = 1; 82 | 83 | for sr = 1:length(sampling_list) 84 | sampling_ratio = sampling_list(sr); 85 | fprintf('Sampling ratio: %.2f\n',sampling_ratio*100); 86 | 87 | % Compute the Walsh Hadamard transform 88 | [target, target_noise] = dspi_differential(H1, img, snr, dim, option_sampling, sampling_ratio); 89 | list_rmse(iter,1, im) = rmse(img, target); % RMSE 90 | list_rmse_noise(iter,1, im) = rmse(img, target_noise); 91 | list_ssim(iter, 1, im) = ssim_index(target*255, img*255); % SSIM 92 | list_ssim_noise(iter, 1, im) = ssim_index(target_noise*255, img*255); 93 | img_nonoise(:,:,iter, 1, im) = target; % Images 94 | img_noise(:,:,iter, 1, im) = target_noise; 95 | 96 | % Compute the Walsh-Paley transform 97 | [target, target_noise] = dspi_differential(H2, img, snr, dim, option_sampling, sampling_ratio); 98 | list_rmse(iter,2,im) = rmse(img, target); % RMSE 99 | list_rmse_noise(iter,2,im) = rmse(img, target_noise); 100 | list_ssim(iter, 2, im) = ssim_index(target*255, img*255); % SSIM 101 | list_ssim_noise(iter, 2, im) = ssim_index(target_noise*255, img*255); 102 | img_nonoise(:,:,iter, 2,im) = target; % Images 103 | img_noise(:,:,iter, 2,im) = target_noise; 104 | 105 | % Compute the Walsh-systems 106 | [target, target_noise] = dspi_differential(H3, img, snr, dim, option_sampling, sampling_ratio); 107 | list_rmse(iter,3,im) = rmse(img, target); % RMSE 108 | list_rmse_noise(iter,3,im) = rmse(img, target_noise); 109 | list_ssim(iter, 3, im) = ssim_index(target*255, img*255); % SSIM 110 | list_ssim_noise(iter, 3, im) = ssim_index(target_noise*255, img*255); 111 | img_nonoise(:,:,iter, 3,im) = target; % Images 112 | img_noise(:,:,iter, 3,im) = target_noise; 113 | 114 | % cake cutting blocks 115 | [target, target_noise] = dspi_differential(H4, img, snr, dim, option_sampling, sampling_ratio); 116 | list_rmse(iter,4,im) = rmse(img, target); % RMSE 117 | list_rmse_noise(iter,4,im) = rmse(img, target_noise); 118 | list_ssim(iter, 4, im) = ssim_index(target*255, img*255); % SSIM 119 | list_ssim_noise(iter, 4, im) = ssim_index(target_noise*255, img*255); 120 | img_nonoise(:,:,iter, 4,im) = target; % Images 121 | img_noise(:,:,iter, 4,im) = target_noise; 122 | 123 | % GCS+S ordering 124 | [target, target_noise] = dspi_differential(H5, img, snr, dim, option_sampling, sampling_ratio); 125 | list_rmse(iter,5,im) = rmse(img, target); % RMSE 126 | list_rmse_noise(iter,5,im) = rmse(img, target_noise); 127 | list_ssim(iter, 5, im) = ssim_index(target*255, img*255); % SSIM 128 | list_ssim_noise(iter, 5, im) = ssim_index(target_noise*255, img*255); 129 | img_nonoise(:,:,iter, 5,im) = target; % Imagenes 130 | img_noise(:,:,iter, 5,im) = target_noise; 131 | 132 | iter = iter + 1; 133 | end 134 | end 135 | 136 | 137 | % - - - - - - - - - - - - - - - - - - - - - - 138 | % Mean and standard deviation 139 | % - - - - - - - - - - - - - - - - - - - - - - 140 | 141 | range = sampling_list; 142 | result1 = zeros(5, len_sl, 2); 143 | result2 = zeros(5, len_sl, 2); 144 | result3 = zeros(5, len_sl, 2); 145 | result4 = zeros(5, len_sl, 2); 146 | 147 | for i=1:5 148 | for j=1:len_sl 149 | % RMSE 150 | result1(i,j,1) = mean(list_rmse(j,i,:)); 151 | result1(i,j,2) = std(list_rmse(j,i,:)); 152 | result2(i,j,1) = mean(list_rmse_noise(j,i,:)); 153 | result2(i,j,2) = std(list_rmse_noise(j,i,:)); 154 | % SSIM 155 | result3(i,j,1) = mean(list_ssim(j,i,:)); 156 | result3(i,j,2) = std(list_ssim(j,i,:)); 157 | result4(i,j,1) = mean(list_ssim_noise(j,i,:)); 158 | result4(i,j,2) = std(list_ssim_noise(j,i,:)); 159 | end 160 | end 161 | 162 | 163 | % - - - - - - - - - - - - - - - - - - - - - - 164 | % RMSE plots 165 | % - - - - - - - - - - - - - - - - - - - - - - 166 | 167 | % Without noise 168 | figure(1) 169 | errorbar(range, result1(2,:,1), result1(2,:,2),'d-','LineWidth',1) 170 | hold on 171 | errorbar(range, result1(3,:,1), result1(3,:,2),'o-','LineWidth',1) 172 | hold on 173 | errorbar(range, result1(4,:,1), result1(4,:,2),'*-','LineWidth',1) 174 | hold on 175 | errorbar(range, result1(5,:,1), result1(5,:,2),'p-','LineWidth',1) 176 | 177 | legend('Walsh-Paley','Sequency','CC','GCS+S') 178 | xlabel('Sampling ratio (%)'); 179 | ylabel('RMSE (Mean +/- Std Dev)') 180 | grid 181 | box on 182 | 183 | 184 | 185 | % With noise 186 | figure(2) 187 | errorbar(range, result2(2,:,1), result2(2,:,2),'d-','LineWidth',1) 188 | hold on 189 | errorbar(range, result2(3,:,1), result2(3,:,2),'o-','LineWidth',1) 190 | hold on 191 | errorbar(range, result2(4,:,1), result2(4,:,2),'*-','LineWidth',1) 192 | hold on 193 | errorbar(range, result2(5,:,1), result2(5,:,2),'p-','LineWidth',1) 194 | 195 | legend('Walsh-Paley','Sequency','CC','GCS+S') 196 | xlabel('Sampling ratio (%)'); 197 | ylabel('RMSE (Mean +/- Std Dev)') 198 | grid 199 | box on 200 | 201 | 202 | 203 | % - - - - - - - - - - - - - - - - - - - - - - 204 | % SSIM Plots 205 | % - - - - - - - - - - - - - - - - - - - - - - 206 | 207 | % Without noise 208 | figure(3) 209 | errorbar(range, result3(2,:,1), result3(2,:,2),'d-','LineWidth',1) 210 | hold on 211 | errorbar(range, result3(3,:,1), result3(3,:,2),'o-','LineWidth',1) 212 | hold on 213 | errorbar(range, result3(4,:,1), result3(4,:,2),'*-','LineWidth',1) 214 | hold on 215 | errorbar(range, result3(5,:,1), result3(5,:,2),'p-','LineWidth',1) 216 | 217 | legend('Walsh-Paley','Sequency','CC','GCS+S') 218 | xlabel('Sampling ratio (%)'); 219 | ylabel('SSIM (Mean +/- Std Dev)') 220 | grid 221 | box on 222 | 223 | 224 | % With noise 225 | figure(4) 226 | errorbar(range, result4(2,:,1), result4(2,:,2),'d-','LineWidth',1) 227 | hold on 228 | errorbar(range, result4(3,:,1), result4(3,:,2),'o-','LineWidth',1) 229 | hold on 230 | errorbar(range, result4(4,:,1), result4(4,:,2),'*-','LineWidth',1) 231 | hold on 232 | errorbar(range, result4(5,:,1), result4(5,:,2),'p-','LineWidth',1) 233 | 234 | legend('Walsh-Paley','Sequency','CC','GCS+S') 235 | xlabel('Sampling ratio (%)'); 236 | ylabel('SSIM (Mean +/- Std Dev)') 237 | grid 238 | box on 239 | -------------------------------------------------------------------------------- /demo5.m: -------------------------------------------------------------------------------- 1 | % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 | % A comparison of image restoration using the Cake Cutting 3 | % and GCS+S methods. The linear equation system is solved using 4 | % a Total Variational algorithm 5 | % - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 6 | 7 | clc 8 | close all 9 | clear 10 | 11 | base_path = pwd; 12 | 13 | base_path = strcat(base_path,'\3DCS\packages\'); 14 | 15 | cd(strcat(base_path,'\TVAL3_beta2.4')) 16 | path(path,genpath(pwd)); 17 | cd('..') 18 | cd('..') 19 | cd('..') 20 | 21 | % - - - - - - - - - - - - - - - - - - 22 | % Generate measurement patterns 23 | % - - - - - - - - - - - - - - - - - - 24 | dim = 7; 25 | size_img = 2^dim; 26 | 27 | % - - - - - - - - - - - - - - - - - - 28 | % Constructing Hadamard matrices 29 | % - - - - - - - - - - - - - - - - - - 30 | 31 | fprintf('Constructing Hadamard matrices.\n') 32 | 33 | if isfile('data/cakecutting128_blocks.mat')==1 34 | load 'data/cakecutting128_blocks.mat' 35 | else 36 | [H, ~, ~] = Cake_Cutting(Walsh_Hadamard_Transform(2*dim), dim, 'blocks'); 37 | end 38 | 39 | H4 = H; 40 | clear H 41 | H5 = GCSS(2*dim, 'dyadic'); 42 | 43 | 44 | 45 | 46 | 47 | % - - - - - - - - - - - - - - - - - - 48 | % Main program for simulation 49 | % - - - - - - - - - - - - - - - - - - 50 | 51 | num_images = 1; 52 | 53 | sampling_list = [0.05 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0]; 54 | len_sl = length(sampling_list); 55 | 56 | snr = 40; 57 | 58 | option_sampling = 1; 59 | list_rmse = zeros(len_sl, 2, num_images); 60 | list_rmse_noise = zeros(len_sl, 2, num_images); 61 | list_ssim = zeros(len_sl, 2, num_images); 62 | list_ssim_noise = zeros(len_sl, 2, num_images); 63 | 64 | % storage for images 65 | img_nonoise = zeros(size_img, size_img, len_sl, 2, num_images); 66 | img_noise = zeros(size_img, size_img, len_sl, 2, num_images); 67 | 68 | 69 | fprintf('Simulation ...\n'); 70 | 71 | list_images = [3713 3309 56622]; 72 | 73 | for im=1:num_images 74 | % Load a random object 75 | index_img = randi(82783); 76 | list_images(im) = index_img; 77 | %index_img = list_images(im); 78 | fprintf('*********** IMAGE %d **********\n', im); 79 | 80 | name = strcat('COCO_train2014_', num2str(index_img), '.jpg'); 81 | path_img = strcat('.\coco-train2014\', name); 82 | img = imread(path_img); 83 | fprintf('Image: %s\n', path_img); 84 | 85 | if size(img,3)==3 86 | img = rgb2gray(img); 87 | end 88 | 89 | % sub-sampled image 90 | img = double(imresize(img, [size_img size_img], 'bilinear')); 91 | img = img/max(max(img)); 92 | 93 | iter = 1; 94 | num_pixel = 128; % number of image pixels in each dimension 95 | 96 | 97 | for sr = 1:length(sampling_list) 98 | sampling_ratio = sampling_list(sr); 99 | fprintf('Sampling ratio: %.2f\n',sampling_ratio*100); 100 | 101 | % - - - - - - - - - - - - - - - 102 | % Cake Cutting blocks 103 | % - - - - - - - - - - - - - - - 104 | 105 | num_pattern = round(sampling_ratio*num_pixel*num_pixel); 106 | 107 | patterns = H4(1:num_pattern,:); 108 | measurements = patterns*img(:); 109 | mavg = mean(abs(measurements)); 110 | sigma = 0.5; 111 | measurements_noise = measurements + sigma*mavg*randn(length(measurements),1); 112 | %measurements_noise = awgn(measurements, snr, 'measured'); 113 | 114 | % Run TVAL3 115 | clear opts 116 | opts.mu = 2^8; 117 | opts.beta = 2^5; 118 | opts.tol = 1E-3; 119 | opts.maxit = 300; 120 | opts.TVnorm = 1; 121 | opts.disp = false; 122 | 123 | % Solve the sparse problem 124 | [target, ~] = TVAL3(patterns, measurements, num_pixel, num_pixel, opts); 125 | [target_noise, ~] = TVAL3(patterns, measurements_noise, num_pixel, num_pixel, opts); 126 | 127 | % restored images 128 | target = abs(target); 129 | target_noise = abs(target_noise); 130 | target = normalize_matrix(target); 131 | target_noise = normalize_matrix(target_noise); 132 | 133 | % save solutions 134 | list_rmse(iter,1,im) = rmse(img, target); % RMSE 135 | list_rmse_noise(iter,1,im) = rmse(img, target_noise); 136 | list_ssim(iter, 1, im) = ssim_index(target*255, img*255); % SSIM 137 | list_ssim_noise(iter, 1, im) = ssim_index(target_noise*255, img*255); 138 | img_nonoise(:,:,iter, 1,im) = target; % Imagenes 139 | img_noise(:,:,iter, 1,im) = target_noise; 140 | 141 | 142 | % - - - - - - - - - - - - - - - 143 | % GCS+S ordering 144 | % - - - - - - - - - - - - - - - 145 | 146 | patterns = H5(1:num_pattern,:); 147 | measurements = patterns*img(:); 148 | mavg = mean(abs(measurements)); 149 | sigma = 0.5; 150 | measurements_noise = measurements + sigma*mavg*randn(length(measurements),1); 151 | %measurements_noise = awgn(measurements, snr, 'measured'); 152 | 153 | % Run TVAL3 154 | clear opts 155 | opts.mu = 2^8; 156 | opts.beta = 2^5; 157 | opts.tol = 1E-3; 158 | opts.maxit = 300; 159 | opts.TVnorm = 1; 160 | opts.disp = false; 161 | 162 | % Solve the sparse problem 163 | [target, ~] = TVAL3(patterns, measurements, num_pixel, num_pixel, opts); 164 | [target_noise, ~] = TVAL3(patterns, measurements_noise, num_pixel, num_pixel, opts); 165 | 166 | % restored images 167 | target = abs(target); 168 | target_noise = abs(target_noise); 169 | target = normalize_matrix(target); 170 | target_noise = normalize_matrix(target_noise); 171 | 172 | % save solutions 173 | list_rmse(iter,2,im) = rmse(img, target); % RMSE 174 | list_rmse_noise(iter,2,im) = rmse(img, target_noise); 175 | list_ssim(iter, 2, im) = ssim_index(target*255, img*255); % SSIM 176 | list_ssim_noise(iter, 2, im) = ssim_index(target_noise*255, img*255); 177 | img_nonoise(:,:,iter, 2,im) = target; % Imagenes 178 | img_noise(:,:,iter, 2,im) = target_noise; 179 | 180 | iter = iter + 1; 181 | end 182 | 183 | end 184 | 185 | 186 | % - - - - - - - - - - - - - - - - - - - - - - 187 | % Mean and standard deviation 188 | % - - - - - - - - - - - - - - - - - - - - - - 189 | 190 | range = sampling_list; 191 | result1 = zeros(2, len_sl, 2); 192 | result2 = zeros(2, len_sl, 2); 193 | result3 = zeros(2, len_sl, 2); 194 | result4 = zeros(2, len_sl, 2); 195 | 196 | for i=1:2 197 | for j=1:len_sl 198 | % RMSE 199 | result1(i,j,1) = mean(list_rmse(j,i,:)); 200 | result1(i,j,2) = std(list_rmse(j,i,:)); 201 | result2(i,j,1) = mean(list_rmse_noise(j,i,:)); 202 | result2(i,j,2) = std(list_rmse_noise(j,i,:)); 203 | % SSIM 204 | result3(i,j,1) = mean(list_ssim(j,i,:)); 205 | result3(i,j,2) = std(list_ssim(j,i,:)); 206 | result4(i,j,1) = mean(list_ssim_noise(j,i,:)); 207 | result4(i,j,2) = std(list_ssim_noise(j,i,:)); 208 | end 209 | end 210 | 211 | 212 | % - - - - - - - - - - - - - - - - - - - - - - 213 | % RMSE plots 214 | % - - - - - - - - - - - - - - - - - - - - - - 215 | 216 | % Without noise 217 | figure(1) 218 | errorbar(range*100, result1(1,:,1), result1(1,:,2),'d-','LineWidth',1) 219 | hold on 220 | errorbar(range*100, result1(2,:,1), result1(2,:,2),'o-','LineWidth',1) 221 | xlabel('Sampling ratio (%)'); 222 | ylabel('RMSE (Mean +/- Std Dev)') 223 | grid 224 | box on 225 | x = [0 100]; 226 | y = [0.1 0.1]; 227 | line(x, y, 'Color', 'Black', 'LineStyle', '--') 228 | legend('Walsh-Paley','Sequency','CC','GCS+S') 229 | set(gca,'FontSize',11) 230 | 231 | 232 | 233 | % With noise 234 | figure(2) 235 | errorbar(range*100, result2(1,:,1), result2(1,:,2),'d-','LineWidth',1) 236 | hold on 237 | errorbar(range*100, result2(2,:,1), result2(2,:,2),'o-','LineWidth',1) 238 | xlabel('Sampling ratio (%)'); 239 | ylabel('RMSE (Mean +/- Std Dev)') 240 | grid 241 | box on 242 | x = [0 100]; 243 | y = [0.1 0.1]; 244 | line(x, y, 'Color', 'Black', 'LineStyle', '--') 245 | legend('Walsh-Paley','Sequency','CC','GCS+S') 246 | set(gca,'FontSize',11) 247 | 248 | 249 | 250 | % - - - - - - - - - - - - - - - - - - - - - - 251 | % SSIM plots 252 | % - - - - - - - - - - - - - - - - - - - - - - 253 | 254 | % Without noise 255 | figure(3) 256 | errorbar(range*100, result3(1,:,1), result3(1,:,2),'d-','LineWidth',1) 257 | hold on 258 | errorbar(range*100, result3(2,:,1), result3(2,:,2),'o-','LineWidth',1) 259 | x = [0 100]; 260 | y = [0.6 0.6]; 261 | line(x, y, 'Color', 'Black', 'LineStyle', '--') 262 | legend('Walsh-Paley','Sequency','CC','GCS+S') 263 | xlabel('Sampling ratio (%)'); 264 | ylabel('SSIM (Mean +/- Std Dev)') 265 | grid 266 | box on 267 | set(gca,'FontSize',11) 268 | 269 | 270 | % With noise 271 | figure(4) 272 | errorbar(range*100, result4(1,:,1), result4(1,:,2),'d-','LineWidth',1) 273 | hold on 274 | errorbar(range*100, result4(2,:,1), result4(2,:,2),'o-','LineWidth',1) 275 | x = [0 100]; 276 | y = [0.6 0.6]; 277 | line(x, y, 'Color', 'Black', 'LineStyle', '--') 278 | legend('Walsh-Paley','Sequency','CC','GCS+S') 279 | xlabel('Sampling ratio (%)'); 280 | ylabel('SSIM (Mean +/- Std Dev)') 281 | grid 282 | box on 283 | set(gca,'FontSize',11) 284 | 285 | --------------------------------------------------------------------------------