How can I replace value in array by graphic file(pattern)?
5 views (last 30 days)
Show older comments
I have a picture (matrix containing only values 1,2,3 and 4). I would like to replace each value by different pattern stored in graphic file,for example I would like to replace each value 1 by line pattern, 2 by cross pattern, etc. in order to obtain visual effect of the picture, thanks to different intensity of the pattern.
For example I have pattern like this:
x = [0 0.5 1 1.5 2 2.5 3 3.5 5];
y = [0 2.5 -2.5 2.5 -2.5 2.5 -2.5 2.5 0];
plot(x,y,'k','LineWidth',4);

and I would like to replace every 4 by this pattern.
I would be grateful for any help :)
2 Comments
Image Analyst
on 2 May 2016
What do you mean by "picture" and "matrix"? It looks like you're talking about line plots, not pictures/images.
Accepted Answer
John BG
on 8 May 2016
Edited: John BG
on 8 May 2016
1.- let's have a look at how you generate the basic blocks
x = [0 0.5 1 1.5 2 2.5 3 3.5 5];
y = [0 2.5 -2.5 2.5 -2.5 2.5 -2.5 2.5 0];
H1=plot(x,y,'k','LineWidth',4);
A=imread('stego01.jpg')
imshow(A)
I tried the following lines replicating basic blocks as you show them in the question and there are 4 problems:
- the line is too thin: once the main image built, the traces are too thin, you need thicker lines in the basic blocks.
- too many pixels: If literally replicating the basic blocks as you build them, as soon as having just some tens of elements in the reference matrix with values ranging [1:4] you really build a huge matrix that the human eye needs not be so refined.
- basic block axes ticking outwards: you don't want the axes ticking marks do you
- basic block needs cropping: if you replicate basic blocks as directly built with plot and figure, you are including unnecessary space around the image, outside the basic block.
2.- So, try the following:
x1 = [0 0.5 1 1.5 2 2.5 3 3.5 5];
y1 = [0 2.5 -2.5 2.5 -2.5 2.5 -2.5 2.5 0];
figure(1);% H1=plot(x1,y1,'k','LineWidth',4); % LineWidth=4 is too thin
H1=plot(x1,y1,'k','LineWidth',16);
ax1=gca;ax1.TickDir='out'
saveas(H1,'stego_block01.jpg');
% savefig(H1,'stego_block01.fig','compact'); % don't use savefig
A1=imread('stego_block01.jpg');
% manually get cropping points: [116 585] [792 51]
A1(:,792:end,:)=[];A1(:,1:115,:)=[]; % horizontal cropping
A1(585:end,:,:)=[];A1(1:51,:,:)=[]; % vertical cropping
A1=A1([1:10:end],[1:10:end],:) % without pixel decimation, the resulting image is too big
figure(2);imshow(A1);
[A1sz1 A1sz2 A1sz3]=size(A1);
x2 = [0 2.5 2.5 2.5 .5 5 2.5 .5 0];
y2 = [0 0.5 1 1.5 2 2.5 -2.5 .5 .5];
figure(3);H2=plot(x2,y2,'k','LineWidth',16);
saveas(H2,'stego_block02.jpg');
% savefig(H2,'stego_block02.fig','compact');
A2=imread('stego_block02.jpg');
A2(:,792:end,:)=[];A2(:,1:115,:)=[]; % horizontal cropping
A2(585:end,:,:)=[];A2(1:51,:,:)=[]; % vertical cropping
A2=A2([1:10:end],[1:10:end],:) % pixel decimation
figure(4);imshow(A2);
[A2sz1 A2sz2 A2sz3]=size(A2);
x3=[0 5 1 1.5 0 2.5 5 3.5 5];
y3=[1 1 1 -1 -2.5 -1 1 1 2.5];
figure(5);H3=plot(x3,y3,'k','LineWidth',16);
saveas(H3,'stego_block03.jpg');
% savefig(H3,'stego_block03.fig','compact');
A3=imread('stego_block03.jpg');
A3(:,792:end,:)=[];A3(:,1:115,:)=[]; % horizontal cropping
A3(585:end,:,:)=[];A3(1:51,:,:)=[]; % vertical cropping
A3=A3([1:10:end],[1:10:end],:) % pixel decimation
figure(6);imshow(A3);
[A3sz1 A3sz2 A3sz3]=size(A3);
x4=[0 1 1 0 2.5 1 1 1 5];
y4=[0 0.5 1 1.5 2 2.5 -2 -2.5 .5];
figure(7);H4=plot(x4,y4,'k','LineWidth',16);
saveas(H4,'stego_block04.jpg');
% savefig(H4,'stego_block04.fig','compact');
A4=imread('stego_block04.jpg');
A4(:,792:end,:)=[];A4(:,1:115,:)=[]; % horizontal cropping
A4(585:end,:,:)=[];A4(1:51,:,:)=[]; % vertical cropping
A4=A4([1:10:end],[1:10:end],:) % pixel decimation
figure(8);imshow(A4);
[A4sz1 A4sz2 A4sz3]=size(A4);
without 1. cropping 2. thicker line 3. pixel decimation

with 1. cropping 2. thicker line 3. pixel decimation

We need chekc size(A1) and assume all blocks identical size to make sure, otherwise there would be gaps and overlapping.
3.- from scalars with range [1:4] to blocks
Let's assume your input is
% B= randi(4,randi(5,1,1),randi(6,1,1))
B=[ 3.00 2.00 2.00 1.00 4.00 2.00
3.00 3.00 2.00 4.00 1.00 3.00
1.00 3.00 4.00 4.00 2.00 1.00]
[Bsz1 Bsz2]=size(B)
instead of C=zeros(Bsz1*A1sz1,Bsz2*A2sz2,3);
C=repmat(A1,Bsz1,Bsz2)
and the replicating loops
for k=1:1:Bsz1
for s=1:1:Bsz2
k1=k+A1sz1;s1=s+A1sz2;
switch B(k,s)
case 1.0
C([1:1:A1sz1]+A1sz1*(k-1),[1:1:A1sz2]+A2sz2*(s-1),:)=A1;
case 2.0
C([1:1:A1sz1]+A1sz1*(k-1),[1:1:A1sz2]+A2sz2*(s-1),:)=A2;
case 3.0
C([1:1:A1sz1]+A1sz1*(k-1),[1:1:A1sz2]+A2sz2*(s-1),:)=A3;
case 4.0
C([1:1:A1sz1]+A1sz1*(k-1),[1:1:A1sz2]+A2sz2*(s-1),:)=A4;
% otherwise is optional, you may want to break if value shows outside [1:4]
end
end
end
the result needs some work
imshow(C)
saveas(C,'stego_result_example.jpg')

It's up to you, but in my opinion, the following would improve the result:
- even thicker lines
- larger reference matrix B
- even higher pixel decimation
- instead of 255 black, use 100 grey
- to include the white space around the basic blocks of the face you show in your comment I suggest you reduce the cropping, so that the basic blocks include a more or less thick frame of zeros around each, that will produce the desired effect of preventing basic blocks hitting each other on the main picture
If you find this answer of any help solving your question,
please click on the thumbs-up vote link,
thanks in advance
John
More Answers (2)
Guillaume
on 3 May 2016
Edited: Guillaume
on 3 May 2016
1. Load your four patterns into a cell array however you want, e.g:
patterns = cell(1, 4);
for patidx = 1:4
patterns{patidx} = imread(fullfile('C:\somewhere\', sprintf('pattern%d.png', patidx)));
end
2. If need be, resize all the patterns so they're the same size. All patterns need to be the same size for the next step to work.
desiredsize = [10 10];
patterns = cellfun(@(pat) imresize(pat, desiredsize), patterns, 'UniformOutput', false);
3. Use simple indexing and cell2mat to create your final image:
finalimage = cell2mat(patterns(grayimage)); %where grayimage is your image with 4 levels
imshow(finalimage);
2 Comments
Guillaume
on 7 May 2016
When reporting an error, give the entire error message, particularly the part that tells you which line and which instruction is causing the error. Without that information, it's anybody's guess at what the problem is.
A complete guess: the problem is with patterns(grayimage) and that would be because there are more than 4 grey levels in your image.
Image Analyst
on 3 May 2016
It looks like that's a raw (not demosaiced) image. Is it?
One way would be to just blur the image a lot.
2 Comments
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!