I am trying to shuffle the pixels of an image using chaotic standard map.But I got an error "Subscript indices must either be real positive integers or logicals."

5 views (last 30 days)
I am trying to shuffle the pixels of an image using chaotic standard map by modifying the code in the link https://in.mathworks.com/matlabcentral/answers/uploaded_files/16542/ChaoticEncyption.m .But I got an error "Subscript indices must either be real positive integers or logicals."
% clear all
clc
g=double(imread('rice.png'));
g=double(g)/255;
subplot(221)
imshow(g)
x=g;
[m,n]=size(g);
mo=m;
K=6;
for i=1:m
for j=1:n
r = mod([(i+j),(j+K*sin(((i+1)*n)/2*pi))],mo);
ggg(i,j)=g(r(1)+1,r(2)+1)
end
end
g=ggg;
subplot(222)
imshow(g,[])
Please help me in this regard.

Accepted Answer

Guillaume
Guillaume on 11 Sep 2016
Well, the problem is obvious. You're essentially doing
r(2) = j + K * sin(x)
Since sin is a real number between -1 and 1, there is absolutely no guarantee that r(2) will be an integer. Thus, you can't use it as a pixel index. You could round it but I'm not sure you could reverse the process (to get the original image back).
Note that the original code and therefore your modifications are not very good. Variable names are extremely bad (should be just add a 'g' for the next variable?), they have no meaning. Also, the code queries the number of columns of the image, but then completely ignores it and goes on to assume that the image is square. This will result in an indexing error if the image is taller than wide.
Other silliness: g = double(g)/255, g is already made double in the previous line. In any, case the whole lot can be replaced by a call to im2double. The subplot syntax used is also undocumented.
sourceimage = im2double(imread('rice.png')); %better variable name, simpler code
%the code assume that the image is greyscale. Better make sure:
assert(ndims(sourceimage) == 2, 'Image is not greyscale');
[height, width] = size(sourceimage);
Kfactor = 6;
scrambledimage = zeros(size(sourceimage));
for column = 1:width %the code will be much faster if the inner loop iterate over rows
for row = 1:height
sourcepixel = mod([row + column, round(column + Kfactor*sin(((row+1)*width)/2*pi))], [height, width]); %mod the second calculation by the width, not the height!
scrambledimage(row, column) = sourceimage(sourcepixel(1) + 1, sourcepixel(2) + 1);
end
end
imshowpair(sourceimage, scrambledimage, 'montage'); %better that subplot
  4 Comments
Walter Roberson
Walter Roberson on 27 Jan 2017
Yes. You can apply the transform enough times to get back to the original. Or you can work out the reverse transform. I showed how to do that in one of the other Questions tagged with catmap

Sign in to comment.

More Answers (0)

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!