# how to sum arrays elements with indexes conditions

129 views (last 30 days)
giacomo on 4 Dec 2017
Edited: giacomo on 20 Dec 2017
Hi everyone. I have a programme that reads in an image and subdivide it in n horizontal bands which height that depends on a nominal diameter. The dimensions of these bands is stored in 'barray'. Now I evaluate the position of some objects using regionprops and I got their Y coordinates in an array called centroidsY. I want to count and sum all of the objects that are inside each band using a loop.
The code that I want to implement can be described like this 'sum in a result array all of the elements that have centroidsY coordinates between the sum of barray elements with index smaller (and smaller/equal) of that of the result array'
I tried doing this:
results = zeros(1,length); %it's not an error I have a variable with the
length of a cell array
for i = 1:length
for j = 1:length
if j == 1 % for when the loop would also pick the 0index
results(j) = sum(centroidsY(centroidsY<sum(barray(1:i))));
else
results(j) = sum(centroidsY(centroidsY>sum(barray(1:i-1))) &
centroidsY(centroidsY<sum(barray(1:i))));
end
end
end
disp(results);
Any suggestions? I was doing logical indexing when I had a similar program with fixed number of bands (4, not defined with an input interface like in this one), but it's my first time doing it with a loop (and varying number of elements). Thanks.
EDIT
To clarify (I hope) a bit, here's the code I used where I knew that we were only using four bands:
one = centroidsY(centroidsY<(barray(1)));
two = centroidsY((barray(1))<centroidsY &
centroidsY<(barray(1)+barray(2)));
three = centroidsY((barray(1)+barray(2))<centroidsY &
centroidsY<(barray(1)+barray(2)+barray(3)));
four = centroidsY((barray(1)+barray(2)+barray(3))<centroidsY &
centroidsY<(barray(1)+barray(2)+barray(3)+barray(4)));
get the total number
none = sum(double(centroidsY<barray(1)));
ntwo = sum(double((barray(1))<centroidsY &
centroidsY<(barray(1)+barray(2))));
nthree = sum(double((barray(1)+barray(2))<centroidsY &
centroidsY<(barray(1)+barray(2)+barray(3))));
nfour = sum(double((barray(1)+barray(2)+barray(3))<centroidsY &
centroidsY<(barray(1)+barray(2)+barray(3)+barray(4))));

Elizabeth Reese on 6 Dec 2017
I think a function that could be useful for you is cumsum with documentation here. Using this function, you can easily find the ranges for each band without recomputing all of the sums.
So if barray is a vector of the heights of the bands, and centroidsY is a vector of y coordinates of the objects, then the objects with a center in the i th band would be given by the logical indices
cumBandsHeights = cumsum(barray);
first = centroidsY < cumBandsHeights(1);
ith = centroidsY >= cumBandsHeights(i-1) & centroidsY < cumBandsHeights(i);
To find the number of those objects, you could use nnz or sum on the logical indices first and ith. If you want to sum the y coordinates of those objects, then you can use the logical array to index into centroidsY and then sum the results.
total1 = sum(centroidsY(first));
or
totali = sum(centroidsY(ith));

#### 1 Comment

giacomo on 20 Dec 2017
Hi Liz, thanks for your help. I just saw your answer, for now I resorted to this:
n = zeros(1,bandlength);
for j = 1:bandlength
if j == 1
n(j) = sum(centroidsY<(barray(j)));
plot(centroidsX,centroidsY,'r+','MarkerSize',10,'LineWidth', 2);
hold on;
else
n(j) = sum(centroidsY>sum(barray(1:j-1)) & centroidsY<sum(barray(1:j)));
plot(centroidsX,centroidsY,'b+','MarkerSize',10,'LineWidth', 2);
hold on;
end
end
But I'm yet to find out how to plot the centroids with same color if in the same band but different color for different bands. Do you have any suggestion for this? If I use rand(1,3) the centroids are ALL of different colors and I don't want that. Thanks.