Search code examples
matlabimage-processingoctavergbhsv

Suspect out of bounds Octave


I'm trying to make a kind of hsv histogram by converting the rgb values of a picture (80*120). This is the code:

function Image_histogram = hsvHistogram(path, count_bins)
        Image = double(imread(path));
        Image_histogram = zeros(3 * count_bins);
        [n m] = size(Image);

        H_vect = zeros(n, m);
        S_vect = zeros(n, m);
        V_vect = zeros(n, m);

        hue_vect = zeros(1, count_bins);
        saturation_vect = zeros(1, count_bins);
        value_vect = zeros(1, count_bins);


        for line = 1 : n
                for row = 1 : m
                        %[H_vect(line, row), S_vect(line, row), V_vect(line, row)] = rgb2hsv(Image(line, row, 1), Image(line, row, 2), Image(line, row, 3));
                endfor
        endfor
        number = 100/count_bins;

        for count = 0 : count_bins - 1
                left = (number * count);
                right = (number * count + number);

                hue_vect(1, count + 1) = (sum(sum(H_vect(:,:) >= left & H_vect(:,:) < right)));
                saturation_vect(1, count + 1) = (sum(sum(S_vect(:,:) >= left & S_vect(:,:) < right)));
                value_vect(1, count + 1) = (sum(sum(V_vect(:,:) >= left & V_vect(:,:) < right)));
        endfor

        Image_histogram = horzcat(hue_vect, saturation_vect, value_vect);


endfunction

When i try to get the HSV matrix i always get the error : hsvHistogram: A(I,J,...): index to dimension 2 out of bounds; value 121 out of bound 120

rgb2hsv is a pixel by pixel converter. It converts R G B to H S V. It is not the built-in rgb2hsv function. The commented line seems to be the one with problems.


Solution

  • The problem is in the size() function.
    If such image is RGB, the matrix Image will be a 3D matrix but in your size() function you just gather two outputs, which will lead to incorrect results.
    You must gather all three outputs (for all three dimensions) and then eventually discard the third one (which we know it is 3). Try doing:

    [n,m,~]=size(Image);
    

    More into details, if your matrix has size n x m x q but you ask just for two outputs, like

    [a,b]=size(Image);
    

    you’ll have a=n and b=m*q.
    These results are obviously incorrect because since q>1 then b>m where m is (again) the actual dimension size and you’ll experience the out-of-bounds error. In other words, the loop will run from 1 to b whereas the matrix has only dimension m (which is less than b).

    As instead you must gather all three dimensions separately:

    [a,b,c]=size(Image);
    

    and (as above) eventually discard some unnecessary output arguments (thanks to the tilde ~ operator).