How to find blockwise mean of HSV local histogram for an image?
1 view (last 30 days)
Show older comments
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.
0 Comments
Accepted Answer
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
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.
0 Comments
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!