public PlanarImage gridToEmage(double[][] dataGrid, String imageName) throws IOException {
    // creates a gray-scale image of the values
    int width = dataGrid[0].length;
    int height = dataGrid.length;

    // Get the number of bands on the image.
    URL imgURL = new URL(Config.getProperty("imgURL"));
    PlanarImage dummyImage = JAI.create("URL", imgURL); // dummy loaded. date to be edited.
    SampleModel sm = dummyImage.getSampleModel();
    int nbands = sm.getNumBands();

    // We assume that we can get the pixels values in a integer array.
    double[] pixelTemp = new double[nbands];

    // Get an iterator for the image.
    RandomIterFactory.create(dummyImage, null);
    WritableRaster rasterData =
        RasterFactory.createBandedRaster(
            DataBuffer.TYPE_BYTE, width, height, nbands, new Point(0, 0));

    for (int i = 0; i < height; i++) {
      for (int j = 0; j < width; j++) {
        dataGrid[i][j] = (dataGrid[i][j] <= 255) ? dataGrid[i][j] : 255;

        pixelTemp[0] = dataGrid[i][j];
        pixelTemp[1] = dataGrid[i][j];
        pixelTemp[2] = dataGrid[i][j];

        rasterData.setPixel(j, i, pixelTemp);
      }
    }

    SampleModel sModel2 =
        RasterFactory.createBandedSampleModel(DataBuffer.TYPE_BYTE, width, height, nbands);

    // Try to create a compatible ColorModel - if the number of bands is
    // larger than 4, it will be null.
    ColorModel cModel2 = PlanarImage.createColorModel(sModel2);

    // Create a TiledImage using the sample and color models.
    TiledImage rectImage = new TiledImage(0, 0, width, height, 0, 0, sModel2, cModel2);

    // Set the data of the tiled image to be the raster.
    rectImage.setData(rasterData);

    // Save the image on a file.
    try {
      ImageIO.write(rectImage, "jpg", new File(imageName + ".jpg"));
      log.info("debug save image : " + imageName + ".jpg");

    } catch (IOException e) {
      log.error(e.getMessage());
      log.error("Error in rectifying  image");
    }

    return rectImage;
  }
  public PlanarImage PostProcessEmage(PlanarImage img) {
    if (maskImgFName != null) {
      int width = img.getWidth();
      int height = img.getHeight();

      // Get the number of bands on the image.
      SampleModel sm = img.getSampleModel();
      int nbands = sm.getNumBands();

      // We assume that we can get the pixels values in a integer array.
      double[] pixel = new double[nbands];

      // Get an iterator for the image.
      RandomIter iterator = RandomIterFactory.create(img, null);
      WritableRaster rasterImage =
          RasterFactory.createBandedRaster(
              DataBuffer.TYPE_BYTE, width, height, nbands, new Point(0, 0));

      double[] pixelNeighb = new double[nbands];
      double[] pixelblack = new double[nbands];
      for (int i = 0; i < nbands; i++) {
        pixelNeighb[i] = 0;
        pixelblack[i] = 0;
      }

      PlanarImage mask = JAI.create("FileLoad", maskImgFName);
      RandomIter iteratorMask = RandomIterFactory.create(mask, null);
      double[] pixelMask = new double[mask.getSampleModel().getNumBands()];

      for (int i = 0; i < width; i++) {
        for (int j = 0; j < height; j++) {
          iteratorMask.getPixel(i, j, pixelMask);
          if (!isBlack(pixelMask)) {
            iterator.getPixel(i, j, pixel);
            if (isWhite(pixel)) {;
            } else {
              rasterImage.setPixel(i, j, pixel);
            }
          } else {
            rasterImage.setPixel(i, j, pixelblack);
          }
        }
      }
      SampleModel sModel2 =
          RasterFactory.createBandedSampleModel(DataBuffer.TYPE_BYTE, width, height, nbands);

      // Try to create a compatible ColorModel - if the number of bands is
      // larger than 4, it will be null.
      ColorModel cModel2 = PlanarImage.createColorModel(sModel2);

      // Create a TiledImage using the sample and color models.
      TiledImage processedImage = new TiledImage(0, 0, width, height, 0, 0, sModel2, cModel2);

      // Set the data of the tiled image to be the raster.
      processedImage.setData(rasterImage);

      // Save the image to a file.
      try {
        ImageIO.write(processedImage, "jpg", new File("proc_" + theme + ".jpg"));
      } catch (IOException e) {
        log.error(e.getMessage());
      }

      // Save the image on a file.
      return processedImage;
    } else {
      // Save the image to a file.
      try {
        ImageIO.write(img, "jpg", new File("NOTproc_" + theme + ".jpg"));
      } catch (IOException e) {
        log.error(e.getMessage());
      }
      return img;
    }
  }
  public PlanarImage createRectifiedImage(PlanarImage Image) {
    int nRows = params.getNumOfRows();
    int nCols = params.getNumOfColumns();
    Point rectifiedPoint;

    // Get the image dimensions of the unrectified image
    int width = Image.getWidth();
    int height = Image.getHeight();
    log.info(nRows + ", " + nCols + "\t" + width + ", " + height);
    // Get an iterator for the image.
    RandomIter iterator = RandomIterFactory.create(Image, null);

    // Get the number of bands on the image.
    SampleModel smO = Image.getSampleModel();
    int nbandsO = smO.getNumBands();

    // We assume that we can get the pixels values in a integer array.
    double[] pixelO = new double[nbandsO];

    // Get an iterator for the image.
    WritableRaster rasterPollenO =
        RasterFactory.createBandedRaster(
            DataBuffer.TYPE_BYTE, nCols, nRows, nbandsO, new Point(0, 0));

    for (int i = 0; i < nCols; i++) {
      for (int j = 0; j < nRows; j++) {
        rectifiedPoint =
            this.getMatchingCoord(
                new Point(i + 1, j + 1)); // coz java array start at 0 matlab its 1.
        if (rectifiedPoint.x >= 1
            && rectifiedPoint.x < width
            && rectifiedPoint.y >= 1
            && rectifiedPoint.y < height) {
          iterator.getPixel(rectifiedPoint.x - 1, rectifiedPoint.y - 1, pixelO);
          rasterPollenO.setPixel(i, j, pixelO);
          // log.info("setpixel: " + i + ", " + j  + ", value " + pixelO[0] + ", " + pixelO[1] + ",
          // " + pixelO[2] + ", " + pixelO[3]);
        } else {

        }
      }
    }

    SampleModel sModel2 =
        RasterFactory.createBandedSampleModel(DataBuffer.TYPE_BYTE, nCols, nRows, nbandsO);

    // Try to create a compatible ColorModel - if the number of bands is
    // larger than 4, it will be null.
    ColorModel cModel2 = PlanarImage.createColorModel(sModel2);

    // Create a TiledImage using the sample and color models.
    TiledImage rectPollenImage = new TiledImage(0, 0, nCols, nRows, 0, 0, sModel2, cModel2);

    // log.info(rasterPollenO.getMinX() + ", " + rasterPollenO.getMinY() );
    // Set the data of the tiled image to be the raster.
    rectPollenImage.setData(rasterPollenO);

    // Save the image to a file.
    try {
      ImageIO.write(rectPollenImage, "jpg", new File("rect" + theme + ".jpg"));
    } catch (IOException e) {
      log.error(e.getMessage());
    }
    return rectPollenImage;
  }