public ImageProcessor projectColor(int[] maxima) {
    ColorProcessor ip = new ColorProcessor(w, h);
    for (int y = 0; y < h; y++) {
      for (int x = 0; x < w; x++) {
        int index = y * w + x;

        float w0 = vertexWeights[index][0];
        float w1 = vertexWeights[index][1];
        float w2 = vertexWeights[index][2];

        int m0 = maxima[vIndices[index][0]];
        int m1 = maxima[vIndices[index][1]];
        int m2 = maxima[vIndices[index][2]];

        int r =
            (int)
                (w0 * ((m0 & 0xff0000) >> 16)
                    + w1 * ((m1 & 0xff0000) >> 16)
                    + w2 * ((m2 & 0xff0000) >> 16));
        int g =
            (int)
                (w0 * ((m0 & 0xff00) >> 8) + w1 * ((m1 & 0xff00) >> 8) + w2 * ((m2 & 0xff00) >> 8));
        int b = (int) (w0 * ((m0 & 0xff)) + w1 * ((m1 & 0xff)) + w2 * ((m2 & 0xff)));

        ip.set(x, y, (r << 16) + (g << 8) + b);
      }
    }
    return ip;
  }
  public void run(ImageProcessor ip) {
    ImageUtils.initMMorph4J();

    if (ip instanceof ByteProcessor) {
      GrayScaleImage img = ImageJAdapter.toGrayScaleImage((ByteProcessor) ip);

      Object obj[] = BuilderTreeOfShapeByUnionFindParallel.getImageInterpolate(img);
      short interpolation0[] = (short[]) obj[0];
      short interpolation1[] = (short[]) obj[1];

      int interpWidth = (img.getWidth() * 4 - 3);
      int interpHeight = (img.getHeight() * 4 - 3);

      ByteProcessor imgOut0 = new ByteProcessor(interpWidth, interpHeight);
      ByteProcessor imgOut1 = new ByteProcessor(interpWidth, interpHeight);

      for (int i = 0; i < interpolation0.length; i++) {
        // imgOut.setPixel(i, (interpolation0[i] + interpolation1[i]) / 2);
        imgOut0.set(i, (interpolation0[i] & 0xFF));
        imgOut1.set(i, (interpolation1[i] & 0xFF));
      }

      ImagePlus imgPlus0 = new ImagePlus("interpolation - max", imgOut0);
      imgPlus0.show("image interpolation - max");
      ImagePlus imgPlus1 = new ImagePlus("interpolation - min", imgOut1);
      imgPlus1.show("image interpolation - min");
    } else if (ip instanceof ColorProcessor) {
      ColorImage img = ImageJAdapter.toColorImage((ColorProcessor) ip);

      int interpWidth = (img.getWidth() * 4 - 3);
      int interpHeight = (img.getHeight() * 4 - 3);

      GrayScaleImage imgR = img.getRed();
      GrayScaleImage imgG = img.getGreen();
      GrayScaleImage imgB = img.getBlue();

      ColorProcessor imgOut0 = new ColorProcessor(interpWidth, interpHeight);
      ColorProcessor imgOut1 = new ColorProcessor(interpWidth, interpHeight);

      Object objR[] = BuilderTreeOfShapeByUnionFindParallel.getImageInterpolate(imgR);
      short interpolation0R[] = (short[]) objR[0];
      short interpolation1R[] = (short[]) objR[1];

      Object objG[] = BuilderTreeOfShapeByUnionFindParallel.getImageInterpolate(imgG);
      short interpolation0G[] = (short[]) objG[0];
      short interpolation1G[] = (short[]) objG[1];

      Object objB[] = BuilderTreeOfShapeByUnionFindParallel.getImageInterpolate(imgB);
      short interpolation0B[] = (short[]) objB[0];
      short interpolation1B[] = (short[]) objB[1];

      for (int i = 0; i < interpolation0R.length; i++) {

        int valor0 =
            ((0 & 0xFF) << 24)
                | ((interpolation0R[i] & 0xFF) << 16)
                | ((interpolation0G[i] & 0xFF) << 8)
                | ((interpolation0B[i] & 0xFF) << 0);

        imgOut0.set(i, valor0);

        int valor1 =
            ((0 & 0xFF) << 24)
                | ((interpolation1R[i] & 0xFF) << 16)
                | ((interpolation1G[i] & 0xFF) << 8)
                | ((interpolation1B[i] & 0xFF) << 0);
        imgOut1.set(i, valor1);
      }

      ImagePlus imgPlus0 = new ImagePlus("interpolation - max", imgOut0);
      imgPlus0.show("image interpolation - max");
      ImagePlus imgPlus1 = new ImagePlus("interpolation - min", imgOut1);
      imgPlus1.show("image interpolation - min");
    }
  }
  public void run(ImageProcessor ip) {
    // Ask the user for the sCol value (color saturation factor)
    GenericDialog gd = new GenericDialog("sCol Value");
    gd.addNumericField("sCol: ", 0.3, 3);
    gd.showDialog();
    if (gd.wasCanceled()) return;
    sCol = gd.getNextNumber();

    // Get the mask for the ROI (selected region)
    ImageProcessor mask = ip.getMask();

    Rectangle roi = ip.getRoi();
    int x = (int) roi.getX();
    int y = (int) roi.getY();
    int w = (int) roi.getWidth();
    int h = (int) roi.getHeight();
    // IJ.write("mask w: "+mask.getWidth()+", mask h: "+mask.getHeight()+", roi w: "+w+", roi h:
    // "+h);
    // Create a new mask based on the selected region, but the size is equivalent to the original
    // image
    ColorProcessor temp = new ColorProcessor(ip.getWidth(), ip.getHeight());
    for (int j = 0; j < ip.getHeight(); j++) {
      for (int i = 0; i < ip.getWidth(); i++) {
        if (j >= y && j < y + h && i >= x && i < x + w) {
          // In the mask region
          if (mask == null) // When ROI is Rectangle
          temp.set(i, j, 1);
          else {
            if (mask.get(i - x, j - y) != 0) temp.set(i, j, 1);
            else temp.set(i, j, 0);
          }
        } else {
          temp.set(i, j, 0);
        }
      }
    }
    ip.setMask(temp); // not necessary
    mask = temp;

    // iterate over all pixels, and desaturate only pixels in ROI
    for (int v = 0; v < ip.getHeight(); v++) {
      for (int u = 0; u < ip.getWidth(); u++) {
        if (mask.get(u, v) != 0) {
          // get int-packed color pixel
          int c = ip.get(u, v);

          // extract RGB components from color pixel
          int r = (c & 0xff0000) >> 16;
          int g = (c & 0x00ff00) >> 8;
          int b = (c & 0x0000ff);

          // compute equivalent gray value
          double yy = 0.299 * r + 0.587 * g + 0.114 * b;

          // linearly interpolate $(yyy) --> (rgb)
          r = (int) (yy + sCol * (r - yy));
          g = (int) (yy + sCol * (g - yy));
          b = (int) (yy + sCol * (b - yy));

          // reassemble color pixel
          c = ((r & 0xff) << 16) | ((g & 0xff) << 8) | b & 0xff;
          ip.set(u, v, c);
        }
      }
    }
    imp.updateAndDraw();
  }