Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.
getAvgs[A_, M_] := Module[{i, j, rArr, gArr, bArr},
   rArr = {};
   gArr = {};
   bArr = {};
   For[i = 1, i <= Length[A], i += 1,
    For[j = 1, j <= Length[A[[1]]], j += 1,
      If[M[[i, j]] == 255,
        Append[rArr, A[[i, j, 1]]];
        Append[gArr, A[[i, j, 2]]];
        Append[bArr, A[[i, j, 3]]];
        ];
      ];
    ];
   Return[{rArr, gArr, bArr}];
   ];

This code returned an array containing three blank arrays {{},{},{}}, meaning none of the Append functions worked. A_ and M_ are two images, A is 24-bit 3-channel colour, while M is black and white. They have the same dimensions, the idea is to use M as a mask to find the average colour of all pixels that are shown by the mask. However, none of the Append functions worked.

Append[{}, ImageData[,Byte][[30, 30, 3]]] correctly returned the value, so the syntax should be fine. When I made the for loop increment a counter, the counter correctly returned the number of masked pixels, so the for loop is working correctly too.

From what I know, Module basically declares the variables locally, preventing variable collisions. Is this correct as well?

share|improve this question
    
Thanks, will ask it there. –  March Ho Apr 3 '13 at 18:29
1  
the direct fix is to use AppendTo, though of course you dont really want to use for loops at all. –  george2079 Apr 3 '13 at 20:14
add comment

migrated from stackoverflow.com Apr 6 '13 at 14:34

This question came from our site for professional and enthusiast programmers.

2 Answers

You are trying to find the mean for each channel of an image after masking. So, your code could be much simpler:

image = ExampleData[{"TestImage", "Lena"}];
mask = DiskMatrix[#1/6, #2] & @@ ImageDimensions@image; 
channels =  Pick[Flatten@#, Flatten@mask, 1] & /@ (ImageData /@ ColorSeparate[image]);
Mean /@ channels
(*
{0.697627, 0.39204, 0.449535}
*)

You may compare this result with the mean over the whole image

Mean /@ Flatten /@ ImageData /@ ColorSeparate[image]
(*
{0.706759, 0.388436, 0.413374}
*)

No loops :)

share|improve this answer
add comment

In case you really want a loop.. this is prefered over using AppendTo..

 getAvgs[A_, M_] := Module[{i, j, rArr, gArr, bArr},
    Transpose[Reap[ 
       For[i = 1, i <= Length[A], i += 1,
          For[j = 1, j <= Length[A[[1]]], j += 1,
             If[M[[i, j]] == 255,
               Sow[A[[i, j]]]
                   ;];];]][[2, 1]]]];

and another way more mathematica-esque..

getAvgs[A_, M_] := 
     Transpose[ Last /@ Select [
        Transpose[{Flatten[ M , 1] , Flatten[A, 1]}] , #[[1]] ==  255 & ]]

(not to disagree about using image tools, but it may be more instructive to learn the basics without that )

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.