Count occurrences in a nested ndarray

Hi All I have a nested array created using: edges = scipy.misc.pilutil.imfilter(prent,'find_edges') edges array([[[ 0, 255, 0], [ 0, 255, 0], [ 0, 255, 0], ..., [ 0, 255, 0], [ 0, 255, 0], [ 0, 255, 0]], [[ 0, 255, 0], [ 0, 0, 0], [ 0, 0, 0], ..., [ 0, 0, 0], [ 0, 0, 0], [ 0, 255, 0]], [[ 0, 255, 0], [ 0, 0, 0], [ 0, 0, 0], ..., [ 0, 0, 0], [ 0, 0, 0], [ 0, 255, 0]], ..., [[ 0, 255, 0], [ 0, 0, 0], [ 0, 0, 0], ..., [ 0, 0, 0], [ 0, 0, 0], [ 0, 255, 0]], [[ 0, 255, 0], [ 0, 0, 0], [ 0, 0, 0], ..., [ 0, 0, 0], [ 0, 0, 0], [ 0, 255, 0]], [[ 0, 255, 0], [ 0, 255, 0], [ 0, 255, 0], ..., [ 0, 255, 0], [ 0, 255, 0], [ 0, 255, 0]]], dtype=uint8) I want to count the number of occurrences of certain unique elements in the array, I know what the elements are that I want to count [0,255,0], [255,0,0] and [0,0,255]. I want to count the number of pixels of a particular color in a picture to determine the edge length and calculate areas and such. array does not have a array.count() method and trying to count the instances using a nested for loop like: for xiter in range(xindex): for yiter in range(yindex): if edges[xiter,yiter,:] == [255,0,0]: groenpixelarea = groenpixelarea + 1 if edges[xiter,yiter,:] == [0,255,0]: rooipixelarea = rooipixelarea + 1 if edges[xiter,yiter,:] == [0,0,255]: bloupixelarea = bloupixelarea + 1 results in: 16 for xiter in range(xindex): 17 for yiter in range(yindex): ---> 18 if edges[xiter,yiter,:].any() == [255,0,0]: 19 groenpixelarea = groenpixelarea + 1 20 if edges[xiter,yiter,:] == [0,255,0]: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() WARNING: Failure executing file: <analiseerverwerkteprent.py> What am I doing wrong? Thanx -- Dewald Pieterse

On Tue, Oct 19, 2010 at 9:09 PM, Dewald Pieterse <dewald.pieterse@gmail.com> wrote:
Hi All I have a nested array created using: edges = scipy.misc.pilutil.imfilter(prent,'find_edges') edges array([[[ 0, 255, 0], [ 0, 255, 0], [ 0, 255, 0], ..., [ 0, 255, 0], [ 0, 255, 0], [ 0, 255, 0]], [[ 0, 255, 0], [ 0, 0, 0], [ 0, 0, 0], ..., [ 0, 0, 0], [ 0, 0, 0], [ 0, 255, 0]], [[ 0, 255, 0], [ 0, 0, 0], [ 0, 0, 0], ..., [ 0, 0, 0], [ 0, 0, 0], [ 0, 255, 0]], ..., [[ 0, 255, 0], [ 0, 0, 0], [ 0, 0, 0], ..., [ 0, 0, 0], [ 0, 0, 0], [ 0, 255, 0]], [[ 0, 255, 0], [ 0, 0, 0], [ 0, 0, 0], ..., [ 0, 0, 0], [ 0, 0, 0], [ 0, 255, 0]], [[ 0, 255, 0], [ 0, 255, 0], [ 0, 255, 0], ..., [ 0, 255, 0], [ 0, 255, 0], [ 0, 255, 0]]], dtype=uint8) I want to count the number of occurrences of certain unique elements in the array, I know what the elements are that I want to count [0,255,0], [255,0,0] and [0,0,255]. I want to count the number of pixels of a particular color in a picture to determine the edge length and calculate areas and such. array does not have a array.count() method and trying to count the instances using a nested for loop like: for xiter in range(xindex): for yiter in range(yindex): if edges[xiter,yiter,:] == [255,0,0]: groenpixelarea = groenpixelarea + 1 if edges[xiter,yiter,:] == [0,255,0]: rooipixelarea = rooipixelarea + 1 if edges[xiter,yiter,:] == [0,0,255]: bloupixelarea = bloupixelarea + 1 results in: 16 for xiter in range(xindex): 17 for yiter in range(yindex): ---> 18 if edges[xiter,yiter,:].any() == [255,0,0]: 19 groenpixelarea = groenpixelarea + 1 20 if edges[xiter,yiter,:] == [0,255,0]: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() WARNING: Failure executing file: <analiseerverwerkteprent.py>
What am I doing wrong?
if (edges[xiter,yiter,:] == [255,0,0]).all() makes element wise comparison and then joins them by all but you should be able to do this for all pixels at one (edges == np.array([255,0,0])[None, None,:]).all(-1).sum() or something like this For more complex patterns there might be something fast in scipy.ndimage. Josef
Thanx -- Dewald Pieterse
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion

On Oct 19, 2010, at 6:09 PM, Dewald Pieterse wrote:
for xiter in range(xindex): for yiter in range(yindex): if edges[xiter,yiter,:] == [255,0,0]: groenpixelarea = groenpixelarea + 1 if edges[xiter,yiter,:] == [0,255,0]: rooipixelarea = rooipixelarea + 1 if edges[xiter,yiter,:] == [0,0,255]: bloupixelarea = bloupixelarea + 1
results in:
16 for xiter in range(xindex): 17 for yiter in range(yindex): ---> 18 if edges[xiter,yiter,:].any() == [255,0,0]: 19 groenpixelarea = groenpixelarea + 1 20 if edges[xiter,yiter,:] == [0,255,0]:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() WARNING: Failure executing file: <analiseerverwerkteprent.py>
The array comparison results in an array of booleans, which cannot be used as a condition in the if statement. You could use if alltrue(edges[xiter,yiter,:] == [255,0,0]): groenpixelarea = groenpixelarea + 1 There are probably much faster ways to do this that do not require iterating over all pixels. You could try groenpixelarea = sum(alltrue(a.reshape((-1,3)) == array([0,0,255]), axis=1)) Hope this helps, Lutz

On Wed, Oct 20, 2010 at 1:32 AM, Lutz Maibaum <lutz.maibaum@gmail.com>wrote:
On Oct 19, 2010, at 6:09 PM, Dewald Pieterse wrote:
for xiter in range(xindex): for yiter in range(yindex): if edges[xiter,yiter,:] == [255,0,0]: groenpixelarea = groenpixelarea + 1 if edges[xiter,yiter,:] == [0,255,0]: rooipixelarea = rooipixelarea + 1 if edges[xiter,yiter,:] == [0,0,255]: bloupixelarea = bloupixelarea + 1
results in:
16 for xiter in range(xindex): 17 for yiter in range(yindex): ---> 18 if edges[xiter,yiter,:].any() == [255,0,0]: 19 groenpixelarea = groenpixelarea + 1 20 if edges[xiter,yiter,:] == [0,255,0]:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() WARNING: Failure executing file: <analiseerverwerkteprent.py>
The array comparison results in an array of booleans, which cannot be used as a condition in the if statement. You could use
if alltrue(edges[xiter,yiter,:] == [255,0,0]): groenpixelarea = groenpixelarea + 1
This worked.
There are probably much faster ways to do this that do not require iterating over all pixels. You could try
groenpixelarea = sum(alltrue(a.reshape((-1,3)) == array([0,0,255]), axis=1))
This worked way faster, awesome.
Hope this helps,
Lutz
Thanks for all the help. -- Dewald Pieterse
participants (3)
-
Dewald Pieterse
-
josef.pktd@gmail.com
-
Lutz Maibaum