title: Fastest way to apply a function to each pixel of image?
body: <p>Started learning python less than a week ago. Maybe my question is really n00b'ish one, but I spent about six hours today trying to find an answer, but failed.</p>
  
  <p>I have found multiple solutions of applying functions to each point in CHANNEL in image (R, G and B) separately, but I need to analyze each pixel on all three channels simultaneously.
  So <a href="https://stackoverflow.com/questions/51997022/fast-way-to-apply-custom-function-to-every-pixel-in-image">this</a> and <a href="https://stackoverflow.com/questions/37863967/pil-apply-the-same-operation-to-every-pixel">that</a> don't fit, or I severely don't understand something.</p>
  
  <p>What I have is an RGB .png image (actually, it's a screenshot made with MSS , so maybe it's faster to work with it directly than save/load? but I don't know exactly <strong>how</strong> to do that... <em>yet</em>).
  The image consists of colored pixels and gray pixels of different brightness.</p>
  
  <p>I need to filter this image into "mode 1" image, in which every pixel is set to <strong>0</strong> (solid|black) or <strong>1</strong> (blank|white) according to following rule: if source pixel (<em>all pixels are [R,G,B]</em>) is colored (R != G or G != B or B != R), the resulting pixel is <strong>1</strong> (blank|white), OR if it's not colored but brighter than #eee , it's <strong>1</strong> (blank|white). Only if source pixel not colored (R == G == B) AND it's darker than #eee, resulting pixel is <strong>0</strong> (solid|black).</p>
  
  <p>Just changing mode / filtering by threshold won't work, since colored pixels can be quite dark. Darker than gray ones, actually.</p>
  
  <p>Maybe there is some library/function that already does what I need, but I quite un-epically failed to find one.</p>
  
  <p>So it's a function like:</p>
  
  <pre><code>#accepts [R,G,B] or (R,G,B)
  def process_pixel(pixel) :
    if (1 == len(set(pixel)) and (238 &gt; pixel[0]) :
      return 0
    else 
      return 1
  </code></pre>
  
  <p>Now I need to apply this function (well, maybe some OTHER, much better function, which I just can't image with my severely limited python knowledge -- yet) to every pixel of image and with this create a new image.</p>
  
  <p>Today I've read about pillow/PIL library and decided to use it (I've also read about openCV library, but that's some kind of monster for handleing <em>computer vision</em>, which kinda shivers me timbers... <strong>a lot</strong>)
  The script looks like this:</p>
  
  <pre><code>from PIL import Image
  
  in_image = Image.open('guineapig.png')
  
  in_pixels = in_image.getdata()
  
  out_pixels = []
  for pixel in in_pixels :
    out_pixels.append(process_pixel(pixel))
  
  out_image = Image.new('1', (*in_image.size, ), (1))
  out_image.putdata(out_pixels)
  out_image.save('guineapig_1.png')
  </code></pre>
  
  <p>Now this works but it's kinda slow. To say the least.
  Since I'm using python less than a week and this is my fourth script, ever, I don't even understand which part slows it down most and what to do with it...</p>