docstr: Measure the intensity of the image with Zernike (N, M)
  
  pixels - the intensity image to be measured
  labels - the labels matrix that labels each object with an integer
  indexes - the label #s in the image
  centers - the centers of the minimum enclosing circle for each object
  radius - the radius of the minimum enclosing circle for each object
  n, m - the Zernike coefficients.
  
  See http://en.wikipedia.org/wiki/Zernike_polynomials for an
  explanation of the Zernike polynomials
docstr_tok: ["Measure","the","intensity","of","the","image","with","Zernike","(","N",",","M",")","pixels","-","the","intensity","image","to","be","measured","labels","-","the","labels","matrix","that","labels","each","object","with","an","integer","indexes","-","the","label","#","s","in","the","image","centers","-","the","centers","of","the","minimum","enclosing","circle","for","each","object","radius","-","the","radius","of","the","minimum","enclosing","circle","for","each","object","n",",","m","-","the","Zernike","coefficients",".","See","http",":","\/\/en.wikipedia.org\/wiki\/Zernike_polynomials","for","an","explanation","of","the","Zernike","polynomials"]
code: def measure_zernike(
      self, pixels, labels, indexes, centers, radius, n, m
  ):
      """Measure the intensity of the image with Zernike (N, M)
  
      pixels - the intensity image to be measured
      labels - the labels matrix that labels each object with an integer
      indexes - the label #s in the image
      centers - the centers of the minimum enclosing circle for each object
      radius - the radius of the minimum enclosing circle for each object
      n, m - the Zernike coefficients.
  
      See http://en.wikipedia.org/wiki/Zernike_polynomials for an
      explanation of the Zernike polynomials
      """
      #
      # The strategy here is to operate on the whole array instead
      # of operating on one object at a time. The most important thing
      # is to avoid having to run the Python interpreter once per pixel
      # in the image and the second most important is to avoid running
      # it per object in case there are hundreds of objects.
      #
      # We play lots of indexing tricks here to operate on the whole image.
      # I'll try to explain some - hopefully, you can reuse.
      center_x = centers[:, 1]
      center_y = centers[:, 0]
  
      #
      # Make up fake values for 0 (the background). This lets us do our
      # indexing tricks. Really, we're going to ignore the background,
      # but we want to do the indexing without ignoring the background
      # because that's easier.
      #
      center_x = numpy.hstack([[0], center_x])
      center_y = numpy.hstack([[0], center_y])
      radius = numpy.hstack([[1], radius])
  
      #
      # Now get one array that's the y coordinate of each pixel and one
      # that's the x coordinate. This might look stupid and wasteful,
      # but these "arrays" are never actually realized and made into
      # real memory.
      #
      # Using 0.0:X creates floating point indices. This makes the
      # data type of x, y consistent with center_x, center_y and
      # raidus. Numpy requires consistent data types for in-place
      # operations like -= and /=.
      #
      y, x = numpy.mgrid[0.0 : labels.shape[0], 0.0 : labels.shape[1]]
  
      #
      # Get the x and y coordinates relative to the object centers.
      # This uses Numpy broadcasting. For each pixel, we use the
      # value in the labels matrix as an index into the appropriate
      # one-dimensional array. So we get the value for that object.
      #
      y -= center_y[labels]
      x -= center_x[labels]
  
      #
      # Zernikes take x and y values from zero to one. We scale the
      # integer coordinate values by dividing them by the radius of
      # the circle. Again, we use the indexing trick to look up the
      # values for each object.
      #
      y /= radius[labels]
      x /= radius[labels]
  
      #
      # Now we can get Zernike polynomials per-pixel where each pixel
      # value is calculated according to its object's MEC.
      #
      # We use a mask of all of the non-zero labels so the calculation
      # runs a little faster.
      #
      zernike_polynomial = (
          centrosome.zernike.construct_zernike_polynomials(
              x, y, numpy.array([[n, m]]), labels > 0
          )
      )
  
      #
      # For historical reasons, centrosome didn't multiply by the per/zernike
      # normalizing factor: 2*n + 2 / E / pi where E is 2 if m is zero and 1
      # if m is one. We do it here to aid with the reconstruction
      #
      zernike_polynomial *= (
          (2 * n + 2) / (2 if m == 0 else 1) / numpy.pi
      )
  
      #
      # Multiply the Zernike polynomial by the image to dissect
      # the image by the Zernike basis set.
      #
      output_pixels = pixels * zernike_polynomial[:, :, 0]
  
      #
      # The sum function calculates the sum of the pixel values for
      # each pixel in an object, using the labels matrix to name
      # the pixels in an object
      #
      zr = scipy.ndimage.sum(output_pixels.real, labels, indexes)
      zi = scipy.ndimage.sum(output_pixels.imag, labels, indexes)
  
      return zr, zi
  
imports: import centrosome.cpmorphology
  import centrosome.zernike
  import numpy
  import scipy.ndimage
  from cellprofiler_core.constants.measurement import COLTYPE_FLOAT
  from cellprofiler_core.module import Module
  from cellprofiler_core.setting.subscriber import ImageSubscriber, LabelSubscriber
  from cellprofiler_core.setting.text import Integer
label_desc: Use image node_id 6 for calling the MeasurementTemplate obj's underlying member method code with example usage: obj.measure_zernike(pixels, labels, indexes, centers, radius, n, m) and returns: zr,  zi