Content-Based Plots and Precision-Repetition Plots Using Color Histograms in MATLAB

So far I have been able to build Precision-Recall plots for grayscale images in the CBIR system. However, I would like to know how to follow the same process for RGB images.

My code:

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;

      

+3


source to share


1 answer


The code you wrote compares the histogram between images, assuming they are in grayscale. If you want to do this for RGB images, you need to determine how many bins you want per plane. Once you do this, for every RGB triplet color you have, you define a 1D linear index so that it essentially acts like a regular 1D histogram. Once you have done that, you can use the above code in the same way as you stated above. Thus, create a function imcolourhist

that takes up the image and the total number of red, green, and blue bins you want. Keep in mind that you cannotspecify 256 bits per dimension. Not only will it be too complex to have any discriminatory power, but you will need 2^24 = 16777216

memory space and MATLAB will most likely give you an in-memory error.

The general procedure should be to determine which riot each color belongs to. Once you do this, you create a 1D linear index, which is essentially the bin for the 1D histogram, and then you increment that value at that location. I am going to use accumarray

to calculate histogram for me. Once we are done, it will substantially replace your call imhist

and you would be performing a histogram intersection on this histogram that will be output from 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

      


Take this code, copy and paste it into a new file, then save it as imcolourhist.m

. Make sure you save this code in the same directory as the above code that you showed us. Note that in accumarray

I am offsetting the linear indices by 1, as the linear indices I generate start at 0

, but MATLAB starts indexing at 1

. Now all you have to do is replace your calls imhist

with imcolourhist

. I would recommend that you select bins for each color channel to be 8 (now num_red_bins = num_green_bins = num_blue_bins = 8

). You will need to play around with this to get good results.

Thus, you would change your code where you calculate the histogram for A

like:



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);

      

Note that I am reading images as color , so the call rgb2gray

is removed. Likewise, for B

you must:

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

      

Please note that I cannot guarantee good results here. Since you are only using a graphical histogram as a method to extract images, you can have a query image and a database image that may have the same color distributions but look completely different in terms of texture and composition. If both of these images have the same color distribution, it will be considered high similarity, although they are not alike.


Good luck!

+6


source







All Articles