title: Python - Find similar colors, best way
body: <p>I've made a function to find a color within a image, and return x, y. Now I need to add a new function, where I can find a color with a given tolerence. Should be easy?</p>
  
  <p>Code to find color in image, and return x, y:</p>
  
  <pre><code>def FindColorIn(r,g,b, xmin, xmax, ymin, ymax):
      image = ImageGrab.grab()
      for x in range(xmin, xmax):
          for y in range(ymin,ymax):
              px = image.getpixel((x, y))
              if px[0] == r and px[1] == g and px[2] == b:
                  return x, y
  
  def FindColor(r,g,b):
      image = ImageGrab.grab()
      size = image.size
      pos = FindColorIn(r,g,b, 1, size[0], 1, size[1])
      return pos
  </code></pre>
  
  <hr>
  
  <p><strong>Outcome:</strong></p>
  
  <p>Taken from the answers the normal methods of comparing two colors are in Euclidean distance, or Chebyshev distance. </p>
  
  <p>I decided to mostly use (squared) euclidean distance, and multiple different color-spaces. LAB, deltaE (LCH), XYZ, HSL, and RGB. In my code, most color-spaces use squared euclidean distance to compute the difference. </p>
  
  <p>For example with LAB, RGB and XYZ a simple squared euc. distance does the trick:</p>
  
  <pre><code>if ((X-X1)^2 + (Y-Y1)^2 + (Z-Z1)^2) &lt;= (Tol^2) then
    ...
  </code></pre>
  
  <p>LCH, and HSL is a little more complicated as both have a cylindrical hue, but some piece of math solves that, then it's on to using squared eucl. here as well.</p>
  
  <p>In most these cases I've added "separate parameters" for tolerance for each channel (using 1 global tolerance, and alternative "modifiers" <code>HueTol := Tolerance * hueMod</code> or <code>LightTol := Tolerance * LightMod</code>).</p>
  
  <hr>
  
  <p>It seems like colorspaces built on top of XYZ (LAB, LCH) does perform best in many of my scenarios. Tho HSL yields very good results in some cases, and it's much cheaper to convert to from RGB, RGB is also great tho, and fills most of my needs.</p>