Search code examples
matlabimage-processinghistogram

How do I write a 3D histogram code without the Matlab built in functions?


I want to creat a histogram code, knowing that it'll be counting the number of occurence of 3 values of a pixel. The idea is I have 3 matrices (L1im, L2im, L3im) representing information extracted from an image, size of each of them is 256*226, and I want to compute how many times a combination of let's say (52,6,40) occurs (each number correspends to a matrix/component but they're all of the same pixel).

I have tried this, but it doesn’t produce the right result:

for i = 1 : 256
    for j = 1 : 256
        for k = 1 : 256
            if  (L1im == i) &  (L2im == j) & (L3im == k)
                myhist(i,j,k)= myhist(i,j,k)+1;
            end
        end
    end
end

Solution

  • Colour Triplets Histogram

    Keeping in mind doing an entire RGB triplet histogram is a large task since you can have 256 × 256 × 256 = 16,777,216 combinations of possible unique colours. A slightly more manageable task I believe is to compute the histogram for the unique RGB values in the image (since the rest will be zero anyways). This is still a fairly large task but might be reasonable if the image is fairly small. Below I believe a decent alternative to binning is to resize the image to a smaller number of pixels. This can be done by using the imresize function. I believe this will decrease fidelity of the image and almost act as a rounding function which can "kinda" simulate the behaviour of binning. In this example I convert the matrices string arrays an concatenate the channels, L1im, L2im and L3im of the image. Below is a demo where I use the image built into MATLAB named saturn.png. A Resize_Factor of 1 will result in the highest amount of bins and the number of bins will decrease as the Resize_Factor increases. Keep in mind that the histogram might require scaling if the image is being resized with the Resize_Factor.

    RGB Triplet Histogram

    Resize_Factor = 200;
    RGB_Image = imread("saturn.png");
    [Image_Height,Image_Width,Number_Of_Colour_Channels] = size(RGB_Image);
    Number_Of_Pixels = Image_Height*Image_Width;
    
    RGB_Image = imresize(RGB_Image,[Image_Height/Resize_Factor Image_Width/Resize_Factor]);
    L1im = RGB_Image(:,:,1);
    L2im = RGB_Image(:,:,2);
    L3im = RGB_Image(:,:,3);
    
    L1im_String = string(L1im);
    L2im_String = string(L2im);
    L3im_String = string(L3im);
    
    RGB_Triplets = L1im_String + "," + L2im_String + "," + L3im_String;
    Unique_RGB_Triplets = unique(RGB_Triplets);
    
    for Colour_Index = 1: length(Unique_RGB_Triplets)
        RGB_Colour = Unique_RGB_Triplets(Colour_Index);
        Unique_RGB_Triplets(Colour_Index,2) = nnz(RGB_Colour == RGB_Triplets); 
    end
    
    Counts = str2double(Unique_RGB_Triplets(:,2));
    Scaling_Factor = Number_Of_Pixels/sum(Counts);
    Counts = Counts.*Scaling_Factor;
    
    if sum(Counts) == Number_Of_Pixels
        disp("Sum of histogram is equal to the number of pixels");
    end
    
    bar(Counts);
    title("RGB Triplet Histogram");
    xlabel("RGB Triplets"); ylabel("Counts");
    
    Current_Axis = gca;
    Scale = (1:length(Unique_RGB_Triplets));
    set(Current_Axis,'xtick',Scale,'xticklabel',Unique_RGB_Triplets);
    Angle = 90;
    xtickangle(Current_Axis,Angle);