How to find blockwise mean of HSV local histogram for an image?

1 view (last 30 days)
I have converted an image from RGB to HSV color space and divided it into 3 * 3 blocks using following code.
HSV = rgb2hsv(im1);
[rows, columns, channel] = size(HSV);
r3 = round(rows/3);
c3 = round(columns/3);
image1 = HSV(1:r3, 1:c3);
[Hval, Sval, Vval]= colour_feature1(image1);
image2 = HSV(1:r3, c3+1:2*c3);
[Hval, Sval, Vval]= colour_feature1(image2);
image3 = HSV(1:r3, 2*c3+1:end);
[Hval, Sval, Vval]= colour_feature1(image3);
image4 = HSV(r3+1:2*r3, 1:c3);
% [Hval, Sval, Vval]= colour_feature(image4);
image5 = HSV(r3+1:2*r3, c3+1:2*c3);
[Hval, Sval, Vval]= colour_feature(image5);
image6 = HSV(r3+1:2*r3, 2*c3+1:end);
[Hval, Sval, Vval]= colour_feature(image6);
image7 = HSV(2*r3+1:end, 1:c3);
[Hval, Sval, Vval]= colour_feature(image7);
image8 = HSV(2*r3+1:end, c3+1:2*c3);
[Hval, Sval, Vval]= colour_feature(image8);
image9 = HSV(2*r3+1:end, 2*c3+1:end);
[Hval, Sval, Vval]= colour_feature(image9);
function[Hval, Sval, Vval] = colour_feature1(HSV)
H=HSV(:,:,1);
S=HSV(:,:,2);
V=HSV(:,:,3);
H=H*360;
h1=H;
s1=S;
v1=V;
h1((h1 > 315) & (h1 <= 360)) = 0;
h1((h1 >= 0) & (h1 <= 25)) = 1;
h1((h1 > 25) & (h1 <= 40)) = 2;
h1((h1 > 40) & (h1 <= 120)) = 3;
h1((h1 > 120) & (h1 <= 190)) = 4;
h1((h1 > 190) & (h1 <= 270)) = 5;
h1((h1 > 270) & (h1 <= 295)) = 6;
h1((h1 > 295) & (h1 <= 315)) = 7;
H=h1;
s1((s1 >= 0) & (s1 <= 0.2)) = 0;
s1((s1 > 0.2) & (s1 <= 0.7)) = 1;
s1((s1 > 0.7) & (s1 <= 1)) = 2;
S=s1;
v1((v1 >= 0) & (v1 <= 0.2)) = 0;
v1((v1 > 0.2) & (v1 <= 0.7)) = 1;
v1((v1 > 0.7) & (v1 <= 1)) = 2;
V=v1;
sumH=sum(sum(H)); Hval=sumH;
sumS=sum(sum(S)); Sval=sumS;
sumV=sum(sum(V)); Vval=sumV;
end
When I executed above code got the following error:
Index exceeds matrix dimensions.
Error in colour_feature1 (line 5)
S=HSV(:,:,2);
Not able to solve it. Please help me.

Accepted Answer

Guillaume
Guillaume on 9 Aug 2018
image1 = HSV(1:r3, 1:c3);
Since you don't specify anything for the 3rd dimension, it's the same as if you specified 1, so the above is equivalent to
image1 = HSV(1:r3, 1:c3, 1);
In effect you've discarded the Saturation and Value channels and transformed your 3D matrix into a 2D matrix, so it's no wonder that in your function when you try to access the 2nd and 3rd channel you get an error.
image1 = HSV(1:r3, 1:c3, :);
would solve that particular issue.
However, your code is horrible! If you start numbering variables, you're doing it wrong. If you keep writing the same lines of code that only differ by one number, you're doing it wrong. All that needs to be replaced by loops and indexing or if possible vectorised code.
For example, you could replace your generation of your blocks by two loops:
HSV = rgb2hsv(im1);
[rows, columns, channel] = size(HSV);
r3 = rows/3; %rounding done later to avoid losing pixels
c3 = columns/3);
blocks = cell(3, 3);
Hval = zeros(3, 3);
Sval = zeros(3, 3);
Vval = zeros(3, 3);
for c = 1:3
for r = 1:3
blocks{r, c} = HSV(round(1+r3*(r-1)) : round(r3*r), round(1+c3*(c-1)) : round(c3*c), :);
[Hval(r, c), Sval(r, c), Vval(r, c)] = colour_feature1(blocks{r, c});
end
end
As for your colour_feature1 function, I recommend you look up discretize;
H = mod(discretize(HSV(:, :, 1)*360, [0 25 40 120 190 270 295 315 360], 'IncludedEdge', 'right') - 1, 7) + 1;
would replace all these lines:
H=HSV(:,:,1);
H=H*360;
h1=H;
h1((h1 > 315) & (h1 <= 360)) = 0;
h1((h1 >= 0) & (h1 <= 25)) = 1;
h1((h1 > 25) & (h1 <= 40)) = 2;
h1((h1 > 40) & (h1 <= 120)) = 3;
h1((h1 > 120) & (h1 <= 190)) = 4;
h1((h1 > 190) & (h1 <= 270)) = 5;
h1((h1 > 270) & (h1 <= 295)) = 6;
h1((h1 > 295) & (h1 <= 315)) = 7;
H=h1;
You can do similar for S and V.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!