MATLAB: Summation of image exceeds matrix dimention

image pixels number within coordinatessum

Using Matlab 2012, I want to count the number of pixels in certain portions of image so i try the following code which give error at sum(sum ) function . could any one help me ? or is there another solution to get the number of pixels within certain coordinates rather than this code:
clear sum
clear all
close all
image=imread('Headers-29.jpg');
image=im2bw(image,graythresh(image)); %binarization
image=imcomplement(image);
[m n]=size(image);
X_segmented=[];
Y_segmented=[];
Width_segmented=[];
Hight_segmented=[];
cropped_segmented={};
Bounding=regionprops( image, 'BoundingBox'); % Minimum x-y coordinates of a block and its x, y lengths
for g=1:length(Bounding)
X_segmented(g,1)=Bounding(g).BoundingBox(1);
Y_segmented(g,1)=Bounding(g).BoundingBox(2);
Width_segmented(g,1)=Bounding(g).BoundingBox(3);
Hight_segmented(g,1)=Bounding(g).BoundingBox(4);
x_Plus(g,1)=X_segmented(g)+Width_segmented(g);
y_plus(g,1)=Y_segmented(g)+Hight_segmented(g);
bvv(g,:)=[X_segmented(g,1) x_Plus(g,1) Y_segmented(g,1) y_plus(g,1)];
end
for g=1:size(bvv,1)
sumnn(g,:)=sum(sum( image(bvv(g,1): bvv(g,2) , bvv(g,3):bvv(g,4))));
end
end

Best Answer

You have two errors in your code. These errors are easy to make because, in my opinion, a) the documentation of regionprops does a poor job of explaining the coordinate system it uses and b) matlab coordinate system is not consistent.
Your first error is that you assume that regionprops return integer coordinates for the upper left point of the bounding box. It does not. It's all explained under <https://www.mathworks.com/help/images/image-coordinate-systems.html#brcu_cr Image Coordinates System - Spatial Coordinates). In short, the corder of pixel centered at (1,1) is (0.5,0.5). In my opinion, it's bonkers. I've complained to matlab about it. It's not going to change. So if you want to use the coordinates returned by regionprops as indices into your image you need to add 0.5 to them or round them up with ceil.
The second error you have made is that regionprops returns coordinates as (x, y) pairs but indexing in matlab uses (row, column) where row <==> y and column <==> x, so you need to swap the pair elements.
Also note, that your first g loop is not needed.
In short, to solve:
props = regionprops(image, 'BoundingBox');
boundingboxes = vertcat(props.BoundingBox); %concatenate all the bounding boxes into Nx4 matrix
%1st column of boundingboxes is the x coordinate == columns, it is a fractional value
%2nd column of boundingboxes is the y coordinate == rows, it is a fractional value
%3rd column is the width
%4th column is the height
%to change to 1st and 2nd to image indices and 3rd and 4th to index of bottom right corner:
boundingboxes(:, [1 2]) = ceil(boundingboxes(:, [1 2]);
boundingboxes(:, [3 4]) = boundingboxes(:, [3 4]) + boundingboxes(:, [1 2]);
%to calculate the sum:
sumnn = zeros(size(boundingbox, 1), 1);
for g = 1:size(boundingbox, 1)
sumnn(g) = sum(sum(image(boundingboxes(g, 2):boundingboxes(g, 4), boundingboxes(g, 1):boundingboxes(g, 4))));
end
Or you can do it all in just two lines if you don't need all these intermediary variables:
props = regionprops(image, 'BoundingBox');
sumnn = arrayfun(@(p) sum(sum(image(floor(p.BoundingBox(2))+(1:p.BoundingBox(4)), floor(p.BoundingBox(1))+(1:p.BoundingBox(3))))), props);
Another option is to request SubarrayIdx rather than BoundingBox since SubarrayIdx is the list of all pixels in the bounding box. This leads to much simpler code:
props = regionprops(image, 'SubarrayIdx');
sumnn = arrayfun(@(p) sum(sum(image(p.SubarrayIdx{:}))), props);