My girlfriend was saying that she may start doing some Cross Stitching and that she may want to make a drawing, image or whatever. In that moment I though "Well, I should be able to create a Matlab code to get any image and convert it to a cross-stitch patter". It turns out I am not the first one to think about this.
But Im not sure if I am doing the right thing.
So lets illustrate an example:
Suppose a pixelated image, any size, any color palette. for example the following screenshot from pixel artist WANEELLA
Suppose that we don't want to scale the image, the result image will have the same amount of pixels as the original (else a imresize
will do).
Now the problem is using only the color palette from the available ones. I decided to use the DCM palette, mainly because I found the RGB conversion of it.
I created away of colour quantization. I use Lab colors to find the closest colour in the DCM palette and use that one.
clear;clc;
% read image (its a gif)
[img,C]=imread('wn.gif');
% Convert it to RGBimage.
img2=img(:,:,:,3);
imgC=zeros([size(img2) 3]);
for ii=1:size(img2,1)
for jj=1:size(img2,2)
imgC(ii,jj,:)=C(img2(ii,jj)+1,:);
end
end
img=imgC;
imshow(img)
% read DCMtoRB conversion
fid=fopen('DCMRGB.txt');
fgets(fid);
ii=0;
tline = fgets(fid);
while ischar(tline)
ii=ii+1;
table{ii}=tline;
tline = fgets(fid);
end
fclose(fid);
for ii=1:size(table,2)
DCMRGB(ii,1)=str2num(table{ii}(1:4));
DCMRGB(ii,4)=hex2dec(table{ii}(end-5:end-4));
DCMRGB(ii,3)=hex2dec(table{ii}(end-7:end-6));
DCMRGB(ii,2)=hex2dec(table{ii}(end-9:end-8));
end
% origColous=reshape(img, [], 3);
Colours=double(unique(reshape(img, [], 3), 'rows'));
Ncol=size(Colours,1);
cform = makecform('srgb2lab');
DCMLab = applycform(DCMRGB(:,2:4)./255,cform);
Colourslab = applycform(Colours,cform);
eudist=@(p)sqrt(p(:,1).^2+p(:,2).^2+p(:,3).^2);
Cind=zeros(Ncol,1);
for ii=1:Ncol
aux=ones(size(DCMLab,1),3);
aux(:,1)=Colourslab(ii,1);
aux(:,2)=Colourslab(ii,2);
aux(:,3)=Colourslab(ii,3);
d=eudist(DCMLab-aux);
[~,Cind(ii)]=min(d);
end
% now DCMRGB will have DCMcode, R, G, B
% Perform map conversion
img2=zeros(size(img));
indimg=zeros(size(img,1),size(img,2));
for ii=1:size(img,1)
for jj=1:size(img,2)
%wich colour is the pixel?
[~,indx]=ismember(double(squeeze(img(ii,jj,:)))',Colours,'rows');
indimg(ii,jj)=Cind(indx);
img2(ii,jj,:)=DCMRGB(Cind(indx),2:4);
end
end
%%
subplot(121)
imshow((img))
% subplot(222)
% [X_dither,map]=rgb2ind(img,DCMRGB(:,2:4)./255,'nodither');
% imshow(uint16(X_dither),map);
subplot(122)
imshow(double(img2)./255)
The result looks like:
However, in this webpage : http://www.picturecraftwork.com/
As you can see, the choice of colours is different in the webpage, and actually it makes more sense and it gives a quite good feeling even without the real colormap.
After a lot of going around, I believe that there could be 2 main things I need to change and implement.
1.- I dont trust 100% the DCMRGB values. I emailed the company seeking more information about theyr color palette.
2.- The brigthness, contrast, hue and saturation values have enormous influence in the output.
how can I modify this 4 values (as in the webpage) in the desired image using Matlab?
DMC2RGB file: (I can copy paste it here if needed)
DCM color pallete: