0

I am new to MATLAB. I have calculated 25 histograms using imhist function, which are created from subdividing the image into 25 blocks (1block=1histogram) using for loop. How can I concatenate these histograms on the same graph to make one histogram where for instance, the histogram for the first block stretches on the x axis from 0 to 255, the histogram for the second block stretches from 256 to 511, and so on until the 25th block. How can I do this?

I had found a solution like this How to concatenate 3 histograms on the same graph in Matlab but my problem is I calculated all 25 histograms using for loop and I don't know what variable should I pass so that I can concatenate all histograms in 1 long histogram as I want it to be. I also found the similar example but it is in python Concatenate multiple histograms in matplotlib

This is what I had done:

%declare variable
B=12; %B represent the block size
overlapp=3; %overlapping block is slid by 3 pixels along the image 
nob=0; %no of blocks

%get input from grayscale image
gray_path = 'D:\gray_image_folder\*.png';
total_gray_images=dir(gray_path);

for noOfGRAYimage = 1:length(total_gray_images)
% Specify images names with full path and extension    
    grayfilename=strcat('D:\gray_image_folder\', total_gray_images(noOfGRAYimage).name);
    grayImage = imread(grayfilename);% Read gray images 
    [r, c, p]=size(grayImage);
      for i=1:overlapp:(r-B)+1; 
  %         fprintf('i = %d\n', i);
  %         numberofblock = sprintf('%s_%d','block',nob)
          for j=1:overlapp:(c-B)+1;
  %             fprintf('j = %d\n', j);
              nob=nob+1;
              fy_mad(nob).block=grayImage(i:i+B-1,j:j+B-1); %partition (12x12) of blocks
              fy_mad(nob).position=[i j]; 
              fy_mad(nob).index=nob; 
              [rb, cb]=size(fy_mad(nob).block); %[12,12]
              localBinaryPatternImage = fy_mad(nob).block;
              %call function LBP
              LBP_centre = LBP (localBinaryPatternImage);
              figure;imhist(uint8(LBP_centre)) %histogram for each block

             % How to concatenate all histograms?
             %////

          end
      end
  end

I tried this according to @crazyGamer

%get input from grayscale image
gray_path = 'D:\gray_image_folder\*.png';
total_gray_images=dir(gray_path);

allCounts = []
allBinLocs = []

for noOfGRAYimage = 1:length(total_gray_images)
% Specify images names with full path and extension    
    grayfilename=strcat('D:\gray_image_folder\', total_gray_images(noOfGRAYimage).name, total_gray_images(noOfGRAYimage).name);
    grayImage = imread(grayfilename);% Read gray images 
    [r, c, p]=size(grayImage);

    for i=1:overlapp:(r-B)+1; 
        for j=1:overlapp:(c-B)+1;
            nob=nob+1;
            fy_mad(nob).block=grayImage(i:i+B-1,j:j+B-1); 
            fy_mad(nob).position=[i j]; 
            fy_mad(nob).index=nob; %number of blocks 

            [rb, cb]=size(fy_mad(nob).block); 
            localBinaryPatternImage = fy_mad(nob).block;

            %call function LBP
            LBP_centre = LBP (localBinaryPatternImage);

           % Let's compute and display the concatenation of all histogram.
            [counts, binLocs] = imhist(uint8(LBP_centre), 256);
            allCounts = [allCounts, counts];
            allBinLocs = [allBinLocs, binLocs + length(allBinLocs)]
            % "+ length(allBinLocs)" is to shift range from 256-511, and so on for each block.

        end
    end
end

figure;
stem(allBinLocs, allCounts);

Here is the result: Concatenate histogram

fy_mad
  • 13
  • 5

1 Answers1

0

Use the return values of imhist to store the bin locations and values, instead of directly plotting them in the loop.

Then, you can concatenate them all in a big array and display the histogram.

allCounts = []
allBinLocs = []

for noOfGRAYimage = 1:length(total_gray_images)
    % ...
    for i=1:overlapp:(r-B)+1; 
        % ...          
        for j=1:overlapp:(c-B)+1;
            % ...

            [counts, binLocs] = imhist(uint8(LBP_centre), 256);
            allCounts = [allCounts; counts(:)];
            allBinLocs = [allBinLocs; binLocs(:) + length(allBinLocs)];
            % "+ length(allBinLocs)" is to shift range from 256-511, and so on for each block.

        end
    end
end

figure;
stem(allBinLocs, allCounts);
crazyGamer
  • 1,119
  • 9
  • 16
  • Thank you for answering me. I tried and there is something wrong with the values in allBinLocs where for instance I have 9 blocks and the values in allBinLocs start from 0-255 for the 1st block and for the 2nd-9th blocks the values repeated from 256-511. I expect the 3rd blocks to have 512-767. What should I change here? – fy_mad Aug 13 '17 at 11:39
  • I tried the same and I am getting a proper range, can you confirm if you have put the variable names, brackets and commas correctly? Alternatively, just do `allBinLocs = 0:256*numBlocks-1` outside the `for` loops, just before `figure;`. – crazyGamer Aug 13 '17 at 14:02
  • I had revised my coding as you suggested above. Can you please look at it? Thank you so much. – fy_mad Aug 14 '17 at 01:47
  • For the alternative way, I got this instead: **Error using stem (line 31) The length of X must match the number of rows of Y. Error in line 72 stem(allBinLocs, allCounts);** – fy_mad Aug 14 '17 at 01:56
  • Can you tell me the output of `size(allBinLocs)` and `size(allCounts)` after using this approach: `allBinLocs = 0:256*nob-1`? – crazyGamer Aug 14 '17 at 03:41
  • `size(allBinLocs)` ans = 1 2304 `size(allCounts)` ans = 256 9 – fy_mad Aug 14 '17 at 03:53
  • As you can see, the data is all there, only in the wrong dimensions (256*9=2304). This could likely be caused by the concatenation used in my code that assumes row vectors. Check my updated code and please try again. In the *unlikely* case it still doesn't work, use `allBinLocs = (0:256*numBlocks-1).'` before plot. – crazyGamer Aug 14 '17 at 04:26
  • You are my savior! The updated code works! Thank you so much for your effort and time. :) – fy_mad Aug 14 '17 at 05:01