Reputation: 3412
I have an assignment where I have to get a RGB image as the input and then draw histograms for three different channels (Red, Green, and Blue) separately using MATLAB.
Here is the code I wrote first:
function histogram_rgb(image)
values1 = zeros(1, 256);
values2 = zeros(1, 256);
values3 = zeros(1, 256);
[rows, cols, c] = size(image);
for c1 = 1:rows
for c2 = 1:cols
values1(1, image(c1, c2, 1)) = values1(1, image(c1, c2, 1)) + 1;
values2(1, image(c1, c2, 2)) = values2(1, image(c1, c2, 2)) + 1;
values3(1, image(c1, c2, 3)) = values3(1, image(c1, c2, 3)) + 1;
end
end
figure;
subplot(1, 3, 1);
bar((1:256), values1);
title('Histogram for the Image - Red');
subplot(1, 3, 2);
bar((1:256), values2);
title('Histogram for the Image - Green');
size(values3)
subplot(1, 3, 3);
bar((1:256), values3);
title('Histogram for the Image - Blue');
end
But this gave me the following error:
Subscript indices must either be real positive integers or logicals.
I've searched for this error and found that it happens when array indexing goes wrong. Then I edited my code, which fixed that error. The only thing I did was edit the following line:
values3(1, image(c1, c2, 3)) = values3(1, image(c1, c2, 3)) + 1;
where the error was. All I did was to add 1 to the index, as follows:
values3(1, image(c1, c2, 3) + 1) = values3(1, image(c1, c2, 3) + 1) + 1;
My question is why does this happens? I mean, this index works fine for the first two arrays, then why not this one Why does it run when I add 1 to the index?
Thanks in advance.
Upvotes: 0
Views: 455
Reputation: 104474
For posterity, the answer is that your image spans in intensity between [0,255]
for some of the channels, but because MATLAB starts indexing at 1, any intensities in a channel that have the value of 0 will give you an out of bounds error. This only happens for some of your channels and so that's why you don't see the error for the other channels. Therefore, you actually need to shift the intensity per channel by 1 to access the right element to populate in the matrix. It should also be noted that if your image is an integer type, like uint8
. If you simply added 1, intensities that were already 255 will saturate to 255 and not go to 256. Therefore, it's important that you temporarily cast the image to double
when calculating the histogram before adding 1.
Therefore, in your double for
loop, do this:
for c1 = 1:rows
for c2 = 1:cols
pix = double(image(c1, c2, :)) + 1; % New
values1(1, pix(1)) = values1(1, pix(1)) + 1; % Change
values2(1, pix(2)) = values2(1, pix(2)) + 1; % Change
values3(1, pix(3)) = values3(1, pix(3)) + 1; % Change
end
end
What is nice with the above is that we convert all of the channels at a single location to double
then add 1 to this after. We can then use each of the channels in this pixel to populate the histogram.
Upvotes: 2
Reputation: 13510
This is a very simple task, provided using the hist
function from matlab:
function histogram_rgb(image)
titles = {'R', 'G', 'B'};
for i=1:3
subplot(1, 3, i);
values = image(:, :, i);
hist(values(:), 1:10:256);
title(titles{i});
end
Upvotes: -1