docs: def thin(image, mask=None, iterations=1):
      '''Thin an image to lines, preserving Euler number
      
      Implements thinning as described in algorithm # 1 from
      Guo, "Parallel Thinning with Two Subiteration Algorithms",
      Communications of the ACM, Vol 32 #3 page 359.
      '''
      global thin_table, eight_connect
      if thin_table is None:
          thin_table = np.zeros((2,512),bool)
          for i in range(512):
              if (i & 16) == 0:
                  # All zeros -> 0
                  continue
              pat = pattern_of(i & ~ 16)
              ipat = pat.astype(int)
              if scind.label(pat, eight_connect)[1] != 1:
                  thin_table[:,i] = True
                  continue
              n1 = ((ipat[0,0] or ipat[0,1]) + (ipat[0,2] or ipat[1,2])+
                    (ipat[2,2] or ipat[2,1]) + (ipat[2,0] or ipat[1,0]))
              n2 = ((ipat[0,1] or ipat[0,2]) + (ipat[1,2] or ipat[2,2])+
                    (ipat[2,1] or ipat[2,0]) + (ipat[1,0] or ipat[0,0]))
              if min(n1,n2) not in (2,3):
                  thin_table[:,i] = True
                  continue
              thin_table[0,i] = ((pat[0,1] or pat[0,2] or not pat[2,2]) and 
                                 pat[1,2])
              thin_table[1,i] = ((pat[2,1] or pat[2,0] or not pat[0,0]) and
                                 pat[1,0])
      if mask is None:
          masked_image = image.copy()
      else:
          masked_image = image.copy()
          masked_image[~mask] = False
      index_i, index_j, masked_image = prepare_for_index_lookup(masked_image, False)
      if iterations is None:
          iterations = len(index_i)
      for i in range(iterations):
          hit_count = len(index_i)
          for j in range(2):
              index_i, index_j, = index_lookup(index_i, index_j, 
                                               masked_image,
                                               thin_table[j], 1)
          if hit_count == len(index_i):
              break
      masked_image = extract_from_image_lookup(image, index_i, index_j)
      if not mask is None:
          masked_image[~mask] = masked_image[~mask]
      return masked_image