Scrambling the Image - matlab

I want to scramble the image using matlab using the algorithm:
Converting the image to gray scale of W X H pixels.
Computing the sum of every row and every column.
Generating the random variables Kc and Kr of range (2^bit depeth-1) of h&w elements respectively.
Finding the modulo2 of the sum.
Rotate the ith row by Kr(i) amount right if modulo2 of sum of rows is zero else rotate it left by kr(i) amount. Similarly for the columns.
Show the image
Problem is in using the circshift command in matlab to rotate the ith row by Kr(i) amount. This function is not using the indexing of the particular row or column.
%%Encryption till scrambled image
rgb = imread('image.jpg');
I=rgb2gray(rgb);
[w,h]=size(I);
imshow(I);
title('Original grayscale');
info = imfinfo('image.jpg');
bit=info.BitDepth;
range=(2^bit)-1;
Kc=randi(range,[1,h]); %generating a random array Kc of h
Kr=randi(range,[1,w]); %generating random array Kr
alpha=sum(I); %sum of all column element creating an linear array of h columns
alpha1=sum(I,2); %sum of all row element creating an linear array of w rows
M=mod(alpha,2); %linear array of h column
M1=mod(alpha1,2); %linear array of w rows
for i=1:h
if M(1:i)==0
I1=circshift(I(:,i),-Kc(i)); %shifts up
else
I1=circshift(I(:,i),Kc(i)); %shifts down
end
end
for j=1:w
if M1(j:1)==0
I2=circshift(I1(j,:),Kr(j)); %shifts right
else
I2=circshift(I1(j,:),-Kr(j)); %shifts left
end
end
figure
imshow(I2);
title('Scrambled Image');`

Related

MATLAB Staying in bounds of Complex matrix

I have a complex matrix cdata, that is 2144x2048. I am getting elements from cdata that are greater than a specified threshold by doing the following:
[row, col] = find(abs(cdata) > threshold);
row and col can have multiple values. Then, I take the row and col values, I perform a calculation to get N samples of the real x-data, and 33 samples of the y-data as follows:
xdata = real(cdata(row(i),col(i)-bw:col(i)+bw))
ydata = real(cdata(row(i)-bw:row(i)+bw,col(i)-bw:col(i)+bw))
where bw is a constant value that determines the number of samples I need to get. During this calculation, specifically the column portion of cdata for the xdata and the row portion of cdata for the ydata, I exceed the bounds of the matrix and MATLAB throws the following error:
??? Subscript indices must either be real positive integers or logicals
How can I ensure that I don't exceed the bounds? I'm ok with having to skip a row/col pair if it is going to exceed the bounds.
The reason you're having problems is because you're not restricting your search to closer then bw from the edge of the matrix. This means its possible to find values above the threshold near the edges of the matrix. When you add or subtract bw from these indices you end up out of bounds. You can restrict your search like this.
[row, col] = find(abs(cdata(bw+1:end-bw,bw+1:end-bw)) > threshold);
row = row + bw;
col = col + bw;
This guarantees your row and column indices are within the bounds so when you grab a region surrounding them you won't go out of bounds.
On a side note. The ydata variable in your code is indexing an entire square region of the matrix and the xdata is only indexing a section of a row. Should your ydata actually be ydata = real(cdata(row(i)-bw:row(i)+bw, col(i)))?

Filtering in Frequency Domain

I have to apply prewit filter to an image in the frequency domain.Here is the procedure I am following.
1) Convert the NxN matrix of image to 2*Nx2*N matrix by padding zeros
2) Center the image transform by multiplying image with (-1)^(x+y)
3) Compute DFT of image matrix
4) Create the filter of dimensions 2Nx2N and the center at coordinates (N,N)
5) Multiply image matrix with filter matrix
6) Calculate inverse DFT of it and extract the real part of result.
7) Decentralize the result by multiplying with (-1)^(x+y)
8) Finally extract the upper left NxN part of the resultant matrix
My code is below:
% mask=[-1,0,1;-1,0,1;-1,0,1];
%read image
signal=imread('cman.pgm');
signal=double(signal);
% image has NxN dimensions
l=size(signal,1);
pad_signal=zeros(2*l,2*l);
pad_signal(1:l,1:l)=signal;
m=size(mask,1);
mask_f=zeros(2*l,2*l);
for i=-1:1
mask_f(l+i,l-1)=-1;
mask_f(l+i,l+1)=1;
end
x=1:2*l;
[x y]=meshgrid(x,x);
% Multiply each pixel f(x,y) with (-1)*(x+y)
pad_signal=pad_signal.*((-1).^(x+y));
mask_f=myDFT(mask_f);
%find the DFT of image
signal_dft=myDFT(pad_signal);
%multiply the filter with image
res=mask_f*signal_dft;
% find the inverse DFT of real values of result
res=real(myIDFT(res));
res=res.*((-1).^(x+y));
%extract the upper left NxN portion of the result
res=res(1:l,1:l);
imshow(uint8(res));
The method above is from an image processing book. What I am confused about is should I be using a window of 3x3 as prewitt filter is of 3x3 or is my current way of using the filter correct? (i.e. by placing the filter values at centre of 2Nx2N filter matrix and setting all other index values to 0) .
If not either of them, then how should the filter be formed to be multiplied with the dft of image.
Your current way of padding the filter to be the same size as the image is basically correct. We often speak loosely about filtering a length M signal with a length 3 filter, but the implicit assumption is that we are padding both to length M, or maybe length M+3-1.
Some details of your approach complicate things:
1) The multiplication by (-1)^(x+y) just translates the DFT and isn't needed. (See Foundations of Signal Processing Table 3.7 "Circular shift in frequency" for the 1D case. In that notation, you are letting k_0 be N/2, so the W_N term in the left column is just toggling between -1 and 1.)
2) Because the Prewitt filter only has a 3x3 non-zero support, your output only needs to be of size N+2 by N+2. The formula to remember here is length(signal) + length(filter) - 1.
Here's how I would approach this:
clear
x = im2double(imread('cameraman.tif'));
[M, N] = size(x);
h = [-1 0 1;
-1 0 1;
-1 0 1];
P = M + size(h,1) - 1;
Q = N + size(h,2) - 1;
xPadded = x;
xPadded(P, Q) = 0;
hPadded = h;
hPadded(P,Q) = 0;
hShifted = circshift(hPadded, [-1 -1]);
H = fft2(hShifted);
X = fft2(xPadded);
Y = H .* X;
y = ifft2(Y);
yCropped = y(1:M, 1:N);
imshow(yCropped,[]);
Here is how I have solved my problem. I first removed step 2 and 7 from the algorithm. Then centered the transform by swapping the first half of the indices with the second half, in both horizontal and vertical direction. I did this to center the transform of the image. Then I undid this after calculating the inverse DFT of the resultant matrix. I am not sure why my above method does not work but it does so now.
1) Convert the NxN matrix of image to 2*Nx2*N matrix by padding zeros
2) Compute DFT of image matrix
3) Centre the transform of the image by swapping the first and second half of rows and columns.
4) Create the filter of dimensions 2Nx2N and the center at coordinates (N,N)
5) Multiply image matrix with filter matrix
6) Calculate inverse DFT of it and extract the real part of result.
7) Decentralize the result by reapplying step 3 on the resultant matrix
8) Finally extract the upper left NxN part of the resultant matrix
The above is the modified version of steps that I have followed when applying my filtering.
Here is my code (edited/new version)
function res=myFreqConv(signal,mask)
signal=double(signal);
l=size(signal,1);
% padding the image matrix with zeros and making it's size equal to
% 2Nx2N
pad_signal=zeros(2*l,2*l);
pad_signal(1:l,1:l)=signal;
m=size(mask,1);
mask_f=zeros(2*l,2*l);
% Creating a mask of 2Nx2N dims where the prewitt filter values are
at
% the center of the mask i.e. the indices are like this
% [(N-1,N-1), (N-1,N), (N-1,N+1);(N,N-1), (N,N), (N,N+1); (N+1,N-1),
(N+1,N), (N+1,N+1)]
for i=-1:1
mask_f(l+i,l-1)=-1;
mask_f(l+i,l+1)=1;
end
% calculate DFT of mask
mask_f=myDFT(mask_f);
signal_dft=myDFT(pad_signal);
% shifting the image transform to center
indices=cell(1,2);
indices{1}=[2*l/2+1:2*l 1:2*l/2];
indices{2}=[2*l/2+1:2*l 1:2*l/2];
signal_dft=signal_dft(indices{:});
%multiply mask with image
res=mask_f.*signal_dft;
res=real(myIDFT(res));
% shifting the image transform back to original
res=res(indices{:});
res=res(1:l,1:l);
end

How to create matrix of nearest neighbours from dataset using matrix of indices - matlab

I have an Nx2 matrix of data points where each row is a data point. I also have an NxK matrix of indices of the K nearest neighbours from the knnsearch function. I am trying to create a matrix that contains in each row the data point followed by the K neighbouring data points, i.e. for K = 2 we would have something like [data1, neighbour1, neighbour2] for each row.
I have been messing round with loops and attempting to index with matrices but to no avail, the fact that each datapoint is 1x2 is confusing me.
My ultimate aim is to calculate gradients to train an RBF network in a similar manner to:
D = (x_dist - y_dist)./(y_dist+(y_dist==0));
temp = y';
neg_gradient = -2.*sum(kron(D, ones(1,2)) .* ...
(repmat(y, 1, ndata) - repmat((temp(:))', ndata, 1)), 1);
neg_gradient = (reshape(neg_gradient, net.nout, ndata))';
You could use something along those lines:
K = 2;
nearest = knnsearch(data, data, 'K', K+1);%// Gets point itself and K nearest ones
mat = reshape(data(nearest.',:).',[],N).'; %// Extracts the coordinates
We generate data(nearest.',:) to get a 3*N-by-2 matrix, where every 3 consecutive rows are the points that correspond to each other. We transpose this to get the xy-coordinates into the same column. (MATLAB is column major, i.e. values in a column are stored consecutively). Then we reshape the data, so every column contains the xy-coordinates of the rows of nearest. So we only need to transpose once more in the end.

How to access particular matrix element for all blocks in entire image?

I have a 512x512 image , which i made 4x4 block for entire image, then i want access the (3rd row , 3rd element) of the all indivial 4x4 matrices and add it to the index values, which i obtained. Please help me on below code.
[row col] = size(a);
m = zeros(row,col);
count = [(row-4)*(col-4)]/4;
outMat = zeros(4,4,count);
l = 0;
for i=2:4:row-4
for j=2:4:col-4
l = l + 1;
outMat(:,:,l) = double(a(i-1:i+2,j-1:j+2));% for each matrix i have to find(3rd row,3rd element of each matrix.
end;
end;
Adding the (3rd row,3rd element):
m(i,j) = sum(sum(a .* w)); %index value of each 4x4 matrix % w = 4x4 matrix.
LUT = m(i,j)+ outMat(3,3);%(3rd row,3rd element each matrix should be added to all m(i,j) values. In which i fail to add all(3rd row,3rd element) of all 4x4 matrices.
I am going to reword your question so that it's easier to understand, as well as allowing it to be easy for me to write an answer.
From your comments in Kostya's post, you have two images img1 and img2 where they are decomposed into 4 x 4 blocks. outMat would be a 3D matrix where each slice contains a 4 x 4 block extracted from img1. From this, you have a matrix m that stores a weighted sum of 4 x 4 blocks stored outMat.
Next, you'll have another matrix, let's call this outMat2, which also is a 3D matrix where each slice is a 4 x 4 block extracted from img2. From this 3D matrix, you wish to extract the third row and third column of each block, add this to the corresponding position of m and store the output into a variable called LUT.
All you have to do is extract a single vector that slices through all of the slices located at the third row and third column. You would then have to reshape this into a matrix that is the same size as m then add this on top of m and store it into a variable called LUT. Bear in mind that if we reshape this into a matrix, the reshaping will be done in column major format, and so you would stack the values by columns. Because your blocks were created row-wise, what we need to do reshape this matrix so that it has size(m,2) rows and size(m,1) columns then transpose it.
Therefore:
vec = outMat2(3,3,:);
vec = vec(:); %// Make sure it's a 1D vector
m2 = reshape(vec, size(m,2), size(m,1)).';
LUT = m + m2;
LUT will contain a 2D matrix where each element contains the weighted sum of the 4 x 4 blocks from img1 with the corresponding third row, third column of each block in img2.
Next time, please update your question so that you have all of the information. We shouldn't have to dig through your comments to figure out what you want.
I think you can do just
LUT = sum( sum( a(3:4:row,3:4,col) * w(3,3) ) );

Matlab bar3 plot

I have a problem with MATLAB bar3 plots: Here is what I have:
m x n Array Values containing values of a measurement.
Another m x n Array Angles Represents the angle at which a value was measured (e.g. the 3rd value was measured at an angle of 90°). The angular values for each measurement value are stored in another variable.
I need a range for my x-axis from -180° to +180°. This alone is no problem. But how do I hand over my measurement values? I have to somehow link them to the angular values. So that each value in Values is somehow linked to it's angular value in Angles. For my y-axis, I can simply count from 0 to the amount of rows of my Values Array.
EXAMPLE:
Valueslooks like:
3 5 6
2 1 7
5 8 2
Angles looks like:
37° 38° 39°
36° 37° 38°
34° 35° 36°
Values(1,1) = 3 was measured at Angles(1,1) = 37° for example.
At each angle, the number of bars varies depending on how many measurements exist for that angle. bar3 needs a matrix input. In order to build a matrix, missing values are filled with NaN.
Warning: NaNs are usually ignored by plotting commands, but bar3 apparently breaks this convention. It seems to replace NaNs by zeros! So at missing values you'll get a zero-height bar (instead of no bar at all).
[uAngles, ~, uAngleLabels] = unique(Angles); %// get unique values and
%// corresponding labels
valuesPerAngle = accumarray(uAngleLabels(:), Values(:), [], #(v) {v});
%// cell array where each cell contains all values corresponding to an angle
N = max(cellfun(#numel, valuesPerAngle));
valuesPerAngle = cellfun(#(c) {[c; NaN(N-numel(c),1)]}, valuesPerAngle);
%// fill with NaNs to make all cells of equal lenght, so that they can be
%// concatenated into a matrix
valuesPerAngle = cat(2, valuesPerAngle{:}); %// matrix of values for each angle,
%// filled with NaNs where needed
bar3(uAngles, valuesPerAngle.'); %'// finally, the matrix can be plotted
ylabel('Angles')
xlabel('Measurement')
With your example Values and Angles this gives: