From: david carollo on
Hello!
Sorry if I haven't write you before, but I was very busy..
Now I have the program for my goal!

4 m.file:
-creaDBsave (for make the database);
-matchingS for the mechanism to make the best match for images/tile)
-creaMosaicoS (principal program)

------------------------
creaDBsave
-----------------------

clc;
clear all;

D=dir('Immagini');

maxi=size(D,1);

DataCell=cell(1);

DataTEMP(1,1:8)=[0];

c=1;

for i=3:maxi

if size(D(i).name,2)>4

if (strcmp(D(i).name(end-3:end), '.jpg')==1)

RGB = imread(['Immagini\',D(i).name]);
ENT = entropy(RGB);
HSV = rgb2hsv(RGB);
Hmed = mean2(HSV(:,:,1));
Smed = mean2(HSV(:,:,2));
Vmed = mean2(HSV(:,:,3));
pathimm=['\Immagini\',D(i).name];
STDh = std2(HSV(:,:,1));
STDs = std2(HSV(:,:,2));
STDv = std2(HSV(:,:,3));

DataCell{c}=[pathimm];

DataTEMP(c,:)=[Hmed,Smed,Vmed,STDh,STDs,STDv,ENT,c];

c=c+1;

end

end

end

DataCell{c}=[DataTEMP];

save DB.mat DataCell -MAT



------------------------------
matchingS
------------------------------

function Y=matching(X)
%X è una matrice di dimensioni MxN

global M N Data cubo eta cella_prec

XblocRGB=X;

%Calcola l'entropia del blocco
Xentr=entropy(XblocRGB);

%Converti il blocco in hsv
Xbloc=rgb2hsv(XblocRGB);

%Preallocazione
Entr=0;

%Calcola il valore medio di HSV del blocco
XHmed = mean2(Xbloc(:,:,1));
XSmed = mean2(Xbloc(:,:,2));
XVmed = mean2(Xbloc(:,:,3));

%Trova la cella del cubo in cui si trova il blocco
X_HSVind(1,1) = floor(XHmed*eta(1))+1;
X_HSVind(1,2) = floor(XSmed*eta(2))+1;
X_HSVind(1,3) = floor(XVmed*eta(3))+1;

if (X_HSVind(1,1)>eta(1))
X_HSVind(1,1)=X_HSVind(1,1)-1;
elseif (X_HSVind(1,2)>eta(2))
X_HSVind(1,2)=X_HSVind(1,2)-1;
elseif (X_HSVind(1,3)>eta(3))
X_HSVind(1,3)=X_HSVind(1,3)-1;
end

%Calcola la deviazione standard del blocco
XSTDh=std2(Xbloc(:,:,1));
XSTDs=std2(Xbloc(:,:,2));
XSTDv=std2(Xbloc(:,:,3));

[num_imm_cella lung_descrittori]=size(cubo{X_HSVind(1,1),X_HSVind(1,2),X_HSVind(1,3)});

xh=X_HSVind(1,1); xs=X_HSVind(1,2); xv=X_HSVind(1,3);
xxh=xh; xxs=xs; xxv=xv;
med_cubo=floor(eta./2);

if (lung_descrittori==1)

if (xh<med_cubo(1))
for i=xh+1:med_cubo(1)
if (size(cubo{i,xxs,xxv},2)~=1)
xxh=i;
break
end
end
elseif (xh>med_cubo(1))
for i=xh-1:-1:med_cubo(1)
if (size(cubo{i,xxs,xxv},2)~=1)
xxh=i;
break
end
end
end

if (xs<=med_cubo(2))
for j=xs:med_cubo(2)
if (size(cubo{xxh,j,xxv},2)~=1)
xxs=j;
break
end
end
else
for j=xs:-1:med_cubo(2)
if (size(cubo{xxh,j,xxv},2)~=1)
xxs=j;
break
end
end
end

if (xv<=med_cubo(3))
for k=xv:med_cubo(3)
if (size(cubo{xxh,xxs,k},2)~=1)
xxv=k;
break
end
end
else
for k=xv:-1:med_cubo(3)
if (size(cubo{xxh,xxs,k},2)~=1)
xxv=k;
break
end
end
end

xh=xxh; xs=xxs; xv=xxv;

if (size(cubo{xh,xs,xv},2)==1)
cubo{xh,xs,xv}=cella_prec;
end

end

[num_imm_cella lung_descrittori]=size(cubo{xh,xs,xv});

XHSVmed(:,1)=XHmed.*ones(num_imm_cella,1);
XHSVmed(:,2)=XSmed.*ones(num_imm_cella,1);
XHSVmed(:,3)=XVmed.*ones(num_imm_cella,1);

[sort_hsv ind_sort_hsv]=sort(sum((cubo{xh,xs,xv}(:,1:3)-XHSVmed).*(cubo{xh,xs,xv}(:,1:3)-XHSVmed),2));

cell_temp(1,1:9)=0;

for p=1:num_imm_cella

cell_temp(p,:)=cubo{xh,xs,xv}(ind_sort_hsv(p),:);

end

cubo{xh,xs,xv}=cell_temp;



XSTD(:,1)=XSTDh.*ones(num_imm_cella,1);
XSTD(:,2)=XSTDs.*ones(num_imm_cella,1);
XSTD(:,3)=XSTDv.*ones(num_imm_cella,1);

%Prendo i primi valori ordinati in maniera crescente
ind=min(50,num_imm_cella);

for k=1:ind

STDtemp(k,1:3)=cubo{xh,xs,xv}(k,4:6);

end

%Trovo la distanza tra le deviazioni standard
distanza_quad_std = sum((XSTD(1:ind,:) - STDtemp).*(XSTD(1:ind,:) - STDtemp),2);

%Ordino le deviazioni standard in maniera crescente
[sort_STD ind_sort_STD]=sort(distanza_quad_std);

%Ordino le immagini secondo l'entropia
ind1=min(30,num_imm_cella);

for q=1:ind1

qq=ind_sort_STD(q);

Entr=cubo{xh,xs,xv}(qq,7);

Delta(q)=abs(Entr-Xentr);


end

%Calcolo quale immagine della cella ha l'entropia più vicina a quella del
%blocco
[sort_entr ind_sort_entr]=sort(Delta);

%Ordino le immagini secondo il numero di volte in cui sono state scelte
ind2=min(20,num_imm_cella);

for v=1:ind2

vv=ind_sort_STD(ind_sort_entr(v));

cho(v)=cubo{xh,xs,xv}(vv,9);

end

[MinChoose ind_min_choose]=min(cho);


%$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

%Calcola l'indice dell'immagine della cella che ha la minima entropy() rispetto
%al blocco ed è stato scelto il minimo numero di volte,
%quindi lo scelgo come tessera del mosaico
ind_imm=ind_sort_STD(ind_sort_entr(ind_min_choose));

%Trova l'indice corrispondente all'immagine più vicina al blocco, sia per
%la distanza euclidea dei valori medi di hsv, sia per la deviazione
%standard minore, sia per l'entropia
Ind_Imm=cubo{xh,xs,xv}(ind_imm,8);


%Incrementa di 1 il numero di volte in cui è stata scelta l'immagine del
%database
cubo{xh,xs,xv}(ind_imm,9)=cubo{xh,xs,xv}(ind_imm,9)+1;

cella_prec=cubo{xh,xs,xv};

nome_imm=Data.DataCell{Ind_Imm};

nome_imm_da_ins=[pwd,nome_imm];

Yrgb=imread(nome_imm_da_ins);

[MY NY LY]=size(Yrgb);
%Ruoto le immagini per non deformarle troppo con imresize()
if ((M>N)&&(NY>MY))||((M<N)&&(NY<MY))
Yrgb=imrotate(Yrgb,90);
end
Yrgb_resize=imresize(Yrgb,[M N]);
Y=Yrgb_resize;



------------------------------------------
creaMosaicoS
------------------------------------------

function creaMosaico

clc
clear all

global M N Data cubo eta cella_prec

%--------------------------%
%Carica il database
%--------------------------%
Data=load('DB.mat');

F=whos('-file','DB.mat');

%-------------------------------------------------------------------------%
%Imposta il numero di immagini del database da cui attingere le tessere del
%mosaico finale
%-------------------------------------------------------------------------%
max_num_imm=size(Data.(F.name),2)-1;

%-------------------------------------------------------------------------%
%La matrice Valori contiene tutti i dati relativi alle immagini del
%database. A questa matrice verrà aggiunta un'ulteriore colonna contenente
%il numero di volte in cui ogni immagine viene utilizzata nel mosaico. Per
%default, tale colonna conterrà tutti zeri.
%-------------------------------------------------------------------------%
Valori=Data.(F.name){max_num_imm+1};
Valori(:,size(Valori,2)+1)=zeros(size(Valori,1),1);%Valori ha 9 colonne!

fprintf('Il programma prende un''immagine in ingresso, la divide in tasselli \ne ne fa il mosaico utilizzando immagini prese da un database\n');
fprintf('\n\nIl numero di immagini del database è: %1d \n\n',max_num_imm);

%-------------------------------------------------------%
%Imposta la scala di riduzione dell'immagine
%-------------------------------------------------------%
scala=input('\nSupponendo di dividere il mosaico in MxN tessere, \ninserisci la minima dimensione di M oppure N: \n\nConsigliato: da 20 in su \n\n');

%---------------------------------------------------------------%
%Numero di intervalli in cui è suddiviso ogni lato del cubo HSV
%---------------------------------------------------------------%
eta=[8 2 2];

%-------------------------------------------------------------------------%
%Inizializza le celle contenenti le immagini del database raggruppate nel
%cubo HSV
%-------------------------------------------------------------------------%
cubo=cell(eta(1),eta(2),eta(3));

for ci=1:eta(1)

for cj=1:eta(2)

for ck=1:eta(3)

cubo{ci,cj,ck}=[0];

end

end

end

%---------------------------------------------%
%Scegli l'immagine di cui fare il fotomosaico
%---------------------------------------------%
[FILENAME, PATHNAME, FILTERINDEX] = uigetfile('*.jpg', 'Scegli l''immagine');

%-------------------------------------------------------%
%Crea la matrice HSV con i valori prelevati dal database
%-------------------------------------------------------%
for i=1:max_num_imm

%------------------------------------------------------------------------%
%Dividi il cubo di lato 1 in eta(1)x eta(2)x eta(3) cubi più piccoli,
%in modo che in ognuno di questi si trovi un certo numero di immagini
%------------------------------------------------------------------------%
HSVind(i,1) = floor(Valori(i,1)*eta(1))+1;
HSVind(i,2) = floor(Valori(i,2)*eta(2))+1;
HSVind(i,3) = floor(Valori(i,3)*eta(3))+1;

%---------------------------------------------------------------------%
%Riempio i cubetti con vettori riga contenenti i descrittori principali
%delle immagini
%---------------------------------------------------------------------%
if (size(cubo{HSVind(i,1),HSVind(i,2),HSVind(i,3)},2)==1)

%Il cubo selezionato contiene solo l'elemento [0], per cui occupo
%la prima riga della cella
cubo{HSVind(i,1),HSVind(i,2),HSVind(i,3)}=Valori(i,:);

else

%Il cubo selezionato ha già almeno un elemento, per cui posiziono i
%successivi incrementando la riga della cella. Tale valore è dato
%dal primo valore che restituisce size().
incr=size(cubo{HSVind(i,1),HSVind(i,2),HSVind(i,3)},1)+1;

cubo{HSVind(i,1),HSVind(i,2),HSVind(i,3)}(incr,:)=Valori(i,:);

end

end

xyzcel=floor(eta./2);
cella_prec=cubo{xyzcel(1),xyzcel(2),xyzcel(3)};

%------------------------------%
%Leggi l'immagine:
%------------------------------%
Argb=imread([FILENAME]);

[Ma Na La]=size(Argb);

fprintf('\nLe dimensioni dell''immagine di partenza sono %1d x %1d \n\n',Ma,Na);

max_size_tess=mcd(Ma,Na);

size_tess=max_size_tess;

numMtemp=floor(Ma/max_size_tess);%numero minimo tessere su una riga
numNtemp=floor(Na/max_size_tess);%numero minimo tessere su una colonna

Mmin=floor(Ma/scala);%numero righe tessere
Nmin=floor(Na/scala);%numero colonne tessere

while (numMtemp<scala) || (numNtemp<scala)
fac=factor(size_tess);
size_tess=size_tess/fac(end);
numMtemp=floor(Ma/size_tess);%numero tessere su una riga
numNtemp=floor(Na/size_tess);%numero tessere su una colonna
end

num_blk_N=numNtemp;
num_blk_M=numMtemp;

M=size_tess;
N=size_tess;

fprintf('Il mosaico finale avrà %1d x %1d tasselli \n\n',num_blk_M,num_blk_N);
fprintf('Ogni tassello ha dimensioni %1d x %1d \n',M,N);

%%
% % % %kmax serve per fare in modo che la funzione bestblk() mi restituisca un
% % % %numero di blocchi non inferiore alla scala, impostata all'inizio del
% % % %programma
% % % kmax=max(Mmin,Nmin);
% % %
% % % %---------------------------------------%
% % % %Trova le dimensioni ottime dei blocchi
% % % %---------------------------------------%
% % % [M N]=bestblk([Ma Na],kmax);
% % %
% % % num_blk_N=floor(Na/N);
% % % num_blk_M=floor(Ma/M);
%%

%-----------------------------------------------------------------------%
%Dividi l'immagine di partenza in blocchi ed effettua il matching con le
%immagini del database
%-----------------------------------------------------------------------%
for i=1:num_blk_M

for j=1:num_blk_N

%Dividi l'immagine di partenza in blocchi
blocco=Argb(M*(i-1)+1:M*i,N*(j-1)+1:N*j,:);

%Effettua il matching dei blocchi
tessera = matchingS(blocco);

%Inserisci le tessere del mosaico nell'immagine finale
Btemp(M*(i-1)+1:M*i,N*(j-1)+1:N*j,:)=tessera;

end

end

% B=hsv2rgb(Btemp);

%-------------------------------------------------------%
%Ricostruisci l'immagine intera
%-------------------------------------------------------%
B=Btemp;

%-------------------------------------------------------%
%Mostra l'immagine originale
%-------------------------------------------------------%
imshow(Argb);

%-------------------------------------------------------%
%Mostra il mosaico
%-------------------------------------------------------%
figure
imshow(B);



It runs, nice quality but need optimization...

Cheers
 | 
Pages: 1
Prev: Tree data structure in MatLab
Next: Image compare