Recupero di immagini basato sul contenuto e richiamo di precisione dei grafici usando gli istogrammi di colore in MATLAB

Finora, sono stato in grado di tracciare grafici Precision-Recall per immagini in scala di grigi in un sistema CBIR. Tuttavia, mi piacerebbe sapere come eseguire lo stesso processo per le immagini RGB.

Il mio codice:

Inp1=rgb2gray(imread('D:\visionImages\c1\1.ppm')); figure, imshow(Inp1), title('Input image 1'); num_bins = 32; A = imhist(Inp1, num_bins); srcFiles = dir('D:\visionImages\c1\*.ppm'); B = zeros(num_bins, 30); ptr=1; for i = 1 : length(srcFiles) filename = strcat('D:\visionImages\c1\',srcFiles(i).name); I = imread(filename); I=rgb2gray(I); B(:,ptr) = imhist(I, num_bins); ptr=ptr+1; end % histogram intersection a = size(A,2); b = size(B,2); K = zeros(a, b); for i = 1:a Va = repmat(A(:,i),1,b); K(i,:) = 0.5*sum(Va + B - abs(Va - B)); end num_images = 30; sims=K relevant_IDs = [1 2 3 4 5 6 7 8 9 10]; num_relevant_images = numel(relevant_IDs); [sorted_sims, locs] = sort(sims, 'descend'); locations_final = arrayfun(@(x) find(locs == x, 1), relevant_IDs) locations_sorted = sort(locations_final) precision = (1:num_relevant_images) ./ locations_sorted; recall = (1:num_relevant_images) / num_relevant_images; plot(recall, precision, 'b.-'); xlabel('Recall'); ylabel('Precision'); title('Precision-Recall Graph'); axis([0 1 0 1.05]); grid; 

Il codice che hai scritto sta confrontando l’istogramma tra le immagini, a condizione che siano in scala di grigi. Se si desidera eseguire questa operazione per le immagini RGB, è necessario determinare quanti contenitori si desidera per piano. Una volta fatto questo, per ogni terna di colors RGB che hai, dovresti determinare un indice 1D lineare in modo che questo agisca essenzialmente come un normale istogramma 1D. Una volta fatto questo, puoi usare il codice sopra nello stesso modo che hai specificato sopra. In quanto tale, creiamo una funzione imcolourhist che riprende l’immagine e il numero totale di contenitori rossi, verdi e blu desiderati. Ricordare che non è ansible specificare 256 contenitori per dimensione. Non solo sarebbe troppo granulare per avere un potere discriminante, ma avresti bisogno di 2^24 = 16777216 posizioni di memoria, e MATLAB ti darà sicuramente un errore di memoria 2^24 = 16777216 .

La procedura generale consisterebbe nel determinare a quale bin ogni colore appartiene in modo indipendente. Una volta fatto ciò, creeresti quindi un indice 1D lineare che è essenzialmente un bin per un istogramma 1D, e quindi incrementerai quel valore in quella posizione. Utilizzerò l’ accumarray per calcolare l’istogramma per me. Una volta terminato, questo sostituirà essenzialmente la tua chiamata imhist e dovrai eseguire l’intersezione dell’istogramma su questo istogramma che viene invece emesso da imcolourhist .

 function [out] = imcolourhist(im, num_red_bins, num_green_bins, num_blue_bins) im = double(im); %// To maintain precision %// Compute total number of bins total_bins = num_red_bins*num_green_bins*num_blue_bins; %// Figure out threshold between bins red_level = 256 / num_red_bins; green_level = 256 / num_green_bins; blue_level = 256 / num_blue_bins; %// Calculate which bins for each colour plane %// each pixel belongs to im_red_levels = floor(im(:,:,1) / red_level); im_green_levels = floor(im(:,:,2) / green_level); im_blue_levels = floor(im(:,:,3) / blue_level); %// Compute linear indices ind = im_blue_levels*num_red_bins*num_green_bins + im_green_levels*num_red_bins + im_red_levels; ind = ind(:); %// Make column vector for accumarray %// Determine 1D histogram - Ensure that every histogram %// generated has the same size of total_bins x 1 out = accumarray(ind+1, 1, [total_bins 1]); end 

Prendi questo codice, copialo e incollalo in un nuovo file, quindi salvalo come imcolourhist.m . Assicurati di salvare questo codice nella stessa directory in cui si trova il codice sopra indicato. Prendi nota che in accumarray , ho sfalsato gli indici lineari di 1, in quanto gli indici lineari che generi inizieranno da 0 , ma MATLAB inizia l’indicizzazione a 1 . Ora, tutto ciò che devi fare ora è sostituire le imhist chiamate imcolourhist con imcolourhist . Ti consiglio di scegliere i bin per canale di colore per avere 8 per ora (es. num_red_bins = num_green_bins = num_blue_bins = 8 Dovrai giocare con questo per ottenere buoni risultati.

In quanto tale, cambieresti il ​​codice in cui stai calcolando l’istogramma per A come:

 Inp1=imread('D:\visionImages\c1\1.ppm'); num_red_bins = 8; num_green_bins = 8; num_blue_bins = 8; num_bins = num_red_bins*num_green_bins*num_blue_bins; A = imcolourhist(Inp1, num_red_bins, num_green_bins, num_blue_bins); 

Nota che sto leggendo le immagini come colore , quindi la chiamata rgb2gray viene rimossa. Allo stesso modo, per B , dovresti fare:

 B = zeros(num_bins, 30); ptr=1; for i = 1 : length(srcFiles) filename = strcat('D:\visionImages\c1\',srcFiles(i).name); I = imread(filename); B(:,ptr) = imcolourhist(I, num_red_bins, num_green_bins, num_blue_bins); ptr=ptr+1; end 

Nota che non posso garantire buoni risultati qui. Poiché utilizzi solo l’istogramma dei colors come metodo per il recupero delle immagini, potresti avere un’immagine di query e un’immagine di database che potrebbero avere le stesse distribuzioni di colors, ma avere un aspetto completamente diverso in termini di struttura e composizione. Se entrambe queste immagini hanno la stessa distribuzione di colore, queste saranno considerate come una somiglianza elevata, anche se non sembrano affatto simili tra loro.


In bocca al lupo!