summation of image exceeds matrix dimention
    4 vues (au cours des 30 derniers jours)
  
       Afficher commentaires plus anciens
    
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
2 commentaires
Réponse acceptée
  Guillaume
      
      
 le 1 Nov 2017
        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);
4 commentaires
  Guillaume
      
      
 le 2 Nov 2017
				I don't understand that: SubarrayIdx works fine but still the bounding box exceeds the matrix dimention. The values returned by SubArrayIdx cannot exceed the size of the input image.
The line
sumnn = arrayfun(@(p) sum(sum(image(floor(p.BoundingBox(2))+(1:p.BoundingBox(4)), floor(p.BoundingBox(1))+(1:p.BoundingBox(3))))), props);
is equivalent to:
summn = zeros(size(props));
for idx = 1:numel(props)
  p = props(idx);
  summn(idx) = sum(sum(image(floor(p.BoundingBox(2))+(1:p.BoundingBox(4)), floor(p.BoundingBox(1))+(1:p.BoundingBox(3)))));
end
p is just a temporary variable to hold the current element of the props array.
I made a mistake, the
floor(p.BoundingBox(1))+(1:p.BoundingBox(3))
is just another way of writing:
floor(p.BoundingBox(1))+1 : floor(p.BoundingBox(1))+ p.BoundingBox(3)
or even more broken down:
left = floor(p.BoundingBox(1)) + 1;
right = left + p.BoundingBox(3);
range = left:right;
Plus de réponses (1)
  Henrik Jacobsen
      
 le 1 Nov 2017
        I tried your code with a random image, of size [309 367]. In my image, g runs from 1 to 15. For g=1, I have
bvv = [6.5000  359.5000   31.5000  290.5000].
So your code is trying to do
sum(sum( image(6.5000:359.5000 , 31.5000:290.5000)));
The x indices exceed the size of the image, which only goes up to 309. In addition, all the indices are half integers, which can't really be used for indexing. So your code clearly does not do what you intend it to do.
Voir également
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


