class_docstr: Image signature generator.
  
  Based on the method of Goldberg, et al. Available at http://www.cs.cmu.edu/~hcwong/Pdfs/icip02.ps
docstr: Normalizes difference matrix in place.
  
  'Step 4' of the paper.  The flattened version of this array is the image signature.
  
  Args:
      difference_array (numpy.ndarray): n x n x l array, where l are the differences between
          the grid point and its neighbors. Typically the output of compute_differentials
      identical_tolerance (Optional[float]): maximum amount two gray values can differ and
          still be considered equivalent (default 2/255)
      n_levels (Optional[int]): bin differences into 2 n + 1 bins (e.g. n_levels=2 -> [-2, -1,
          0, 1, 2])
  
  Examples:
      >>> img = gis.preprocess_image('https://pixabay.com/static/uploads/photo/2012/11/28/08/56/mona-lisa-67506_960_720.jpg')
      >>> window = gis.crop_image(img)
      >>> grid = gis.compute_grid_points(img, window=window)
      >>> grey_levels = gis.compute_mean_level(img, grid[0], grid[1])
      >>> m = gis.compute_differentials(grey_levels)
      >>> m
      array([[[ 0.,  0.,  0.,  0.,  0.,  0.,  2.,  2.],
              [ 0.,  0.,  0.,  0.,  0.,  2.,  2.,  2.],
              [ 0.,  0.,  0.,  0.,  2.,  2.,  2.,  2.],
              [ 0.,  0.,  0., -2.,  2.,  2.,  1.,  2.],
              [ 0.,  0.,  0., -2.,  2., -1., -1.,  2.],
              [ 0.,  0.,  0., -2., -2., -2., -2., -1.],
              [ 0.,  0.,  0.,  2., -1.,  2.,  2.,  2.],
              [ 0.,  0.,  0.,  1., -1.,  2.,  2., -1.],
              [ 0.,  0.,  0.,  1.,  0.,  2., -1.,  0.]],
  
             [[ 0., -2., -2.,  0., -2.,  0.,  2.,  2.],
              [-2., -2., -2.,  2.,  2.,  2.,  2.,  2.],
              [-2., -2., -2., -2., -2.,  1.,  2., -2.],
              [-2., -1.,  1.,  2.,  1.,  2., -1.,  1.],
              [-2.,  1.,  2., -1.,  2., -1.,  0.,  2.],
              ...
docstr_tok: ["Normalizes","difference","matrix","in","place",".","'Step","4","'","of","the","paper",".","The","flattened","version","of","this","array","is","the","image","signature",".","Args",":","difference_array","(","numpy.ndarray",")",":","n","x","n","x","l","array",",","where","l","are","the","differences","between","the","grid","point","and","its","neighbors",".","Typically","the","output","of","compute_differentials","identical_tolerance","(","Optional","[","float","]",")",":","maximum","amount","two","gray","values","can","differ","and","still","be","considered","equivalent","(","default","2\/255",")","n_levels","(","Optional","[","int","]",")",":","bin","differences","into","2","n","+","1","bins","(","e.g",".","n_levels=2","-",">","[","-2",",","-1",",","0",",","1",",","2","]",")","Examples",":",">",">",">","img","=","gis.preprocess_image","(","'https",":","\/\/pixabay.com\/static\/uploads\/photo\/2012\/11\/28\/08\/56\/mona-lisa-67506_960_720.jpg","'",")",">",">",">","window","=","gis.crop_image","(","img",")",">",">",">","grid","=","gis.compute_grid_points","(","img",",","window=window",")",">",">",">","grey_levels","=","gis.compute_mean_level","(","img",",","grid","[","0","]",",","grid","[","1","]",")",">",">",">","m","=","gis.compute_differentials","(","grey_levels",")",">",">",">","m","array","(","[","[","[","0.",",","0.",",","0.",",","0.",",","0.",",","0.",",","2.",",","2",".","]",",","[","0.",",","0.",",","0.",",","0.",",","0.",",","2.",",","2.",",","2",".","]",",","[","0.",",","0.",",","0.",",","0.",",","2.",",","2.",",","2.",",","2",".","]",",","[","0.",",","0.",",","0.",",","-2.",",","2.",",","2.",",","1.",",","2",".","]",",","[","0.",",","0.",",","0.",",","-2.",",","2.",",","-1.",",","-1.",",","2",".","]",",","[","0.",",","0.",",","0.",",","-2.",",","-2.",",","-2.",",","-2.",",","-1",".","]",",","[","0.",",","0.",",","0.",",","2.",",","-1.",",","2.",",","2.",",","2",".","]",",","[","0.",",","0.",",","0.",",","1.",",","-1.",",","2.",",","2.",",","-1",".","]",",","[","0.",",","0.",",","0.",",","1.",",","0.",",","2.",",","-1.",",","0",".","]","]",",","[","[","0.",",","-2.",",","-2.",",","0.",",","-2.",",","0.",",","2.",",","2",".","]",",","[","-2.",",","-2.",",","-2.",",","2.",",","2.",",","2.",",","2.",",","2",".","]",",","[","-2.",",","-2.",",","-2.",",","-2.",",","-2.",",","1.",",","2.",",","-2",".","]",",","[","-2.",",","-1.",",","1.",",","2.",",","1.",",","2.",",","-1.",",","1",".","]",",","[","-2.",",","1.",",","2.",",","-1.",",","2.",",","-1.",",","0.",",","2",".","]",",","..."]
code: def normalize_and_threshold(
      difference_array, identical_tolerance=2 / 255.0, n_levels=2
  ):
      """Normalizes difference matrix in place.
  
      'Step 4' of the paper.  The flattened version of this array is the image signature.
  
      Args:
          difference_array (numpy.ndarray): n x n x l array, where l are the differences between
              the grid point and its neighbors. Typically the output of compute_differentials
          identical_tolerance (Optional[float]): maximum amount two gray values can differ and
              still be considered equivalent (default 2/255)
          n_levels (Optional[int]): bin differences into 2 n + 1 bins (e.g. n_levels=2 -> [-2, -1,
              0, 1, 2])
  
      Examples:
          >>> img = gis.preprocess_image('https://pixabay.com/static/uploads/photo/2012/11/28/08/56/mona-lisa-67506_960_720.jpg')
          >>> window = gis.crop_image(img)
          >>> grid = gis.compute_grid_points(img, window=window)
          >>> grey_levels = gis.compute_mean_level(img, grid[0], grid[1])
          >>> m = gis.compute_differentials(grey_levels)
          >>> m
          array([[[ 0.,  0.,  0.,  0.,  0.,  0.,  2.,  2.],
                  [ 0.,  0.,  0.,  0.,  0.,  2.,  2.,  2.],
                  [ 0.,  0.,  0.,  0.,  2.,  2.,  2.,  2.],
                  [ 0.,  0.,  0., -2.,  2.,  2.,  1.,  2.],
                  [ 0.,  0.,  0., -2.,  2., -1., -1.,  2.],
                  [ 0.,  0.,  0., -2., -2., -2., -2., -1.],
                  [ 0.,  0.,  0.,  2., -1.,  2.,  2.,  2.],
                  [ 0.,  0.,  0.,  1., -1.,  2.,  2., -1.],
                  [ 0.,  0.,  0.,  1.,  0.,  2., -1.,  0.]],
  
                 [[ 0., -2., -2.,  0., -2.,  0.,  2.,  2.],
                  [-2., -2., -2.,  2.,  2.,  2.,  2.,  2.],
                  [-2., -2., -2., -2., -2.,  1.,  2., -2.],
                  [-2., -1.,  1.,  2.,  1.,  2., -1.,  1.],
                  [-2.,  1.,  2., -1.,  2., -1.,  0.,  2.],
                  ...
  
      """
  
      # set very close values as equivalent
      mask = np.abs(difference_array) < identical_tolerance
      difference_array[mask] = 0.0
  
      # if image is essentially featureless, exit here
      if np.all(mask):
          return None
  
      # bin so that size of bins on each side of zero are equivalent
      positive_cutoffs = np.percentile(
          difference_array[difference_array > 0.0],
          np.linspace(0, 100, n_levels + 1),
      )
      negative_cutoffs = np.percentile(
          difference_array[difference_array < 0.0],
          np.linspace(100, 0, n_levels + 1),
      )
  
      for level, interval in enumerate(
          [
              positive_cutoffs[i : i + 2]
              for i in range(positive_cutoffs.shape[0] - 1)
          ]
      ):
          difference_array[
              (difference_array >= interval[0])
              & (difference_array <= interval[1])
          ] = (level + 1)
  
      for level, interval in enumerate(
          [
              negative_cutoffs[i : i + 2]
              for i in range(negative_cutoffs.shape[0] - 1)
          ]
      ):
          difference_array[
              (difference_array <= interval[0])
              & (difference_array >= interval[1])
          ] = -(level + 1)
  
      return None
  
imports: from skimage.color import rgb2gray
  from skimage.io import imread
  from PIL import Image
  from PIL.MpoImagePlugin import MpoImageFile
  from six import string_types, text_type
  from io import BytesIO
  import numpy
  import xml.etree
  import xml.etree.ElementTree
label_desc: Use image node_id 8 for calling the ImageSignature obj's underlying member method code with example usage: obj.normalize_and_threshold(difference_array, identical_tolerance, n_levels) and returns: None, None