Пример #1
0
  /**
   * Sets image to be processed.
   *
   * @param xsize width of image
   * @param ysize height of image
   * @param buf pixel data
   * @param rect the bounding rectangle defines the region of the image to be recognized. A
   *     rectangle of zero dimension or <code>null</code> indicates the whole image.
   * @param bpp bits per pixel, represents the bit depth of the image, with 1 for binary bitmap, 8
   *     for gray, and 24 for color RGB.
   */
  private void setImage(int xsize, int ysize, ByteBuffer buf, Rectangle rect, int bpp) {
    int bytespp = bpp / 8;
    int bytespl = (int) Math.ceil(xsize * bpp / 8.0);
    api.TessBaseAPISetImage(handle, buf, xsize, ysize, bytespp, bytespl);

    if (rect != null && !rect.isEmpty()) {
      api.TessBaseAPISetRectangle(handle, rect.x, rect.y, rect.width, rect.height);
    }
  }
Пример #2
0
  /**
   * Make a Gaussian blur kernel.
   *
   * @param radius the blur radius
   * @return the kernel
   */
  public static Kernel makeKernel(float radius) {
    int r = (int) Math.ceil(radius);
    int rows = r * 2 + 1;
    float[] matrix = new float[rows];
    float sigma = radius / 3;
    float sigma22 = 2 * sigma * sigma;
    float sigmaPi2 = 2 * ImageMath.PI * sigma;
    float sqrtSigmaPi2 = (float) Math.sqrt(sigmaPi2);
    float radius2 = radius * radius;
    float total = 0;
    int index = 0;
    for (int row = -r; row <= r; row++) {
      float distance = row * row;
      if (distance > radius2) matrix[index] = 0;
      else matrix[index] = (float) Math.exp(-(distance) / sigma22) / sqrtSigmaPi2;
      total += matrix[index];
      index++;
    }
    for (int i = 0; i < rows; i++) matrix[i] /= total;

    return new Kernel(rows, 1, matrix);
  }
Пример #3
0
  public static BufferedImage convolvedown(BufferedImage img, Coord tsz, Convolution filter) {
    Raster in = img.getRaster();
    int w = in.getWidth(), h = in.getHeight(), nb = in.getNumBands();
    double xf = (double) w / (double) tsz.x, ixf = 1.0 / xf;
    double yf = (double) h / (double) tsz.y, iyf = 1.0 / yf;
    double[] ca = new double[nb];
    WritableRaster buf = byteraster(new Coord(tsz.x, h), nb);
    double support = filter.support();

    {
      double[] cf = new double[tsz.x * (int) Math.ceil(2 * support * xf + 2)];
      int[] cl = new int[tsz.x];
      int[] cr = new int[tsz.x];
      for (int x = 0, ci = 0; x < tsz.x; x++) {
        int si = ci;
        double wa = 0.0;
        cl[x] = Math.max((int) Math.floor((x + 0.5 - support) * xf), 0);
        cr[x] = Math.min((int) Math.ceil((x + 0.5 + support) * xf), w - 1);
        for (int sx = cl[x]; sx <= cr[x]; sx++) {
          double tx = ((sx + 0.5) * ixf) - x - 0.5;
          double fw = filter.cval(tx);
          wa += fw;
          cf[ci++] = fw;
        }
        wa = 1.0 / wa;
        for (; si < ci; si++) cf[si] *= wa;
      }
      for (int y = 0; y < h; y++) {
        for (int x = 0, ci = 0; x < tsz.x; x++) {
          for (int b = 0; b < nb; b++) ca[b] = 0.0;
          for (int sx = cl[x]; sx <= cr[x]; sx++) {
            double fw = cf[ci++];
            for (int b = 0; b < nb; b++) ca[b] += in.getSample(sx, y, b) * fw;
          }
          for (int b = 0; b < nb; b++) buf.setSample(x, y, b, Utils.clip((int) ca[b], 0, 255));
        }
      }
    }

    WritableRaster res = byteraster(tsz, nb);
    {
      double[] cf = new double[tsz.y * (int) Math.ceil(2 * support * yf + 2)];
      int[] cu = new int[tsz.y];
      int[] cd = new int[tsz.y];
      for (int y = 0, ci = 0; y < tsz.y; y++) {
        int si = ci;
        double wa = 0.0;
        cu[y] = Math.max((int) Math.floor((y + 0.5 - support) * yf), 0);
        cd[y] = Math.min((int) Math.ceil((y + 0.5 + support) * yf), h - 1);
        for (int sy = cu[y]; sy <= cd[y]; sy++) {
          double ty = ((sy + 0.5) * iyf) - y - 0.5;
          double fw = filter.cval(ty);
          wa += fw;
          cf[ci++] = fw;
        }
        wa = 1.0 / wa;
        for (; si < ci; si++) cf[si] *= wa;
      }
      for (int x = 0; x < tsz.x; x++) {
        for (int y = 0, ci = 0; y < tsz.y; y++) {
          for (int b = 0; b < nb; b++) ca[b] = 0.0;
          for (int sy = cu[y]; sy <= cd[y]; sy++) {
            double fw = cf[ci++];
            for (int b = 0; b < nb; b++) ca[b] += buf.getSample(x, sy, b) * fw;
          }
          for (int b = 0; b < nb; b++) res.setSample(x, y, b, Utils.clip((int) ca[b], 0, 255));
        }
      }
    }
    return (new BufferedImage(img.getColorModel(), res, false, null));
  }
Пример #4
0
  /*
   * This method creates and fills three arrays, Y, Cb, and Cr using the
   * input image.
   */
  private void getYCCArray() {
    int[] values = new int[imageWidth * imageHeight];
    int r;
    int g;
    int b;
    int y;
    int x;

    // In order to minimize the chance that grabPixels will throw an exception
    // it may be necessary to grab some pixels every few scanlines and process
    // those before going for more.  The time expense may be prohibitive.
    // However, for a situation where memory overhead is a concern, this may be
    // the only choice.
    PixelGrabber grabber =
        new PixelGrabber(
            imageobj.getSource(), 0, 0, imageWidth, imageHeight, values, 0, imageWidth);
    MaxHsampFactor = 1;
    MaxVsampFactor = 1;

    for (y = 0; y < NumberOfComponents; y++) {
      MaxHsampFactor = Math.max(MaxHsampFactor, HsampFactor[y]);
      MaxVsampFactor = Math.max(MaxVsampFactor, VsampFactor[y]);
    }

    for (y = 0; y < NumberOfComponents; y++) {
      compWidth[y] =
          ((((imageWidth % 8) != 0)
                      ? (((int) Math.ceil((double) imageWidth / 8.0)) * 8)
                      : imageWidth)
                  / MaxHsampFactor)
              * HsampFactor[y];

      if (compWidth[y] != ((imageWidth / MaxHsampFactor) * HsampFactor[y])) {
        lastColumnIsDummy[y] = true;
      }

      // results in a multiple of 8 for compWidth
      // this will make the rest of the program fail for the unlikely
      // event that someone tries to compress an 16 x 16 pixel image
      // which would of course be worse than pointless
      BlockWidth[y] = (int) Math.ceil((double) compWidth[y] / 8.0);
      compHeight[y] =
          ((((imageHeight % 8) != 0)
                      ? (((int) Math.ceil((double) imageHeight / 8.0)) * 8)
                      : imageHeight)
                  / MaxVsampFactor)
              * VsampFactor[y];

      if (compHeight[y] != ((imageHeight / MaxVsampFactor) * VsampFactor[y])) {
        lastRowIsDummy[y] = true;
      }

      BlockHeight[y] = (int) Math.ceil((double) compHeight[y] / 8.0);
    }

    try {
      if (grabber.grabPixels() != true) {
        try {
          throw new AWTException("Grabber returned false: " + grabber.status());
        } catch (Exception e) {
          String2.log(MustBe.throwableToString(e));
        }
      }
    } catch (InterruptedException e) {
    }

    ;
    float[][] Y = new float[compHeight[0]][compWidth[0]];
    float[][] Cr1 = new float[compHeight[0]][compWidth[0]];
    float[][] Cb1 = new float[compHeight[0]][compWidth[0]];
    float[][] Cb2 = new float[compHeight[1]][compWidth[1]];
    float[][] Cr2 = new float[compHeight[2]][compWidth[2]];
    int index = 0;

    for (y = 0; y < imageHeight; ++y) {
      for (x = 0; x < imageWidth; ++x) {
        r = ((values[index] >> 16) & 0xff);
        g = ((values[index] >> 8) & 0xff);
        b = (values[index] & 0xff);

        // The following three lines are a more correct color conversion but
        // the current conversion technique is sufficient and results in a higher
        // compression rate.
        //                Y[y][x] = 16 + (float)(0.8588*(0.299 * (float)r + 0.587 * (float)g + 0.114
        // * (float)b ));
        //                Cb1[y][x] = 128 + (float)(0.8784*(-0.16874 * (float)r - 0.33126 * (float)g
        // + 0.5 * (float)b));
        //                Cr1[y][x] = 128 + (float)(0.8784*(0.5 * (float)r - 0.41869 * (float)g -
        // 0.08131 * (float)b));
        Y[y][x] = (float) (((0.299 * (float) r) + (0.587 * (float) g) + (0.114 * (float) b)));
        Cb1[y][x] =
            128 + (float) (((-0.16874 * (float) r) - (0.33126 * (float) g) + (0.5 * (float) b)));
        Cr1[y][x] =
            128 + (float) (((0.5 * (float) r) - (0.41869 * (float) g) - (0.08131 * (float) b)));
        index++;
      }
    }

    // Need a way to set the H and V sample factors before allowing downsampling.
    // For now (04/04/98) downsampling must be hard coded.
    // Until a better downsampler is implemented, this will not be done.
    // Downsampling is currently supported.  The downsampling method here
    // is a simple box filter.
    Components[0] = Y;

    //        Cb2 = DownSample(Cb1, 1);
    Components[1] = Cb1;

    //        Cr2 = DownSample(Cr1, 2);
    Components[2] = Cr1;
  }
Пример #5
0
  protected void doDrawOnTo(BufferedImageRaster canvas) {
    Sector sector = this.getSector();
    if (null == sector) {
      String message = Logging.getMessage("nullValue.SectorIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    if (!sector.intersects(canvas.getSector())) {
      return;
    }

    java.awt.Graphics2D g2d = null;
    java.awt.Shape prevClip = null;
    java.awt.Composite prevComposite = null;
    java.lang.Object prevInterpolation = null, prevAntialiasing = null;

    try {
      int canvasWidth = canvas.getWidth();
      int canvasHeight = canvas.getHeight();

      // Apply the transform that correctly maps the image onto the canvas.
      java.awt.geom.AffineTransform transform =
          this.computeSourceToDestTransform(
              this.getWidth(),
              this.getHeight(),
              this.getSector(),
              canvasWidth,
              canvasHeight,
              canvas.getSector());

      AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
      Rectangle2D rect = op.getBounds2D(this.getBufferedImage());

      int clipWidth =
          (int) Math.ceil((rect.getMaxX() >= canvasWidth) ? canvasWidth : rect.getMaxX());
      int clipHeight =
          (int) Math.ceil((rect.getMaxY() >= canvasHeight) ? canvasHeight : rect.getMaxY());

      if (clipWidth <= 0 || clipHeight <= 0) {
        return;
      }

      g2d = canvas.getGraphics();

      prevClip = g2d.getClip();
      prevComposite = g2d.getComposite();
      prevInterpolation = g2d.getRenderingHint(RenderingHints.KEY_INTERPOLATION);
      prevAntialiasing = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);

      // Set the alpha composite for appropriate alpha blending.
      g2d.setComposite(java.awt.AlphaComposite.SrcOver);
      g2d.setRenderingHint(
          RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

      g2d.drawImage(this.getBufferedImage(), transform, null);
    }
    //        catch (java.awt.image.ImagingOpException ioe)
    //        {
    //            // If we catch a ImagingOpException, then the transformed image has a width or
    // height of 0.
    //            // This indicates that there is no intersection between the source image and the
    // canvas,
    //            // or the intersection is smaller than one pixel.
    //        }
    //        catch (java.awt.image.RasterFormatException rfe)
    //        {
    //            // If we catch a RasterFormatException, then the transformed image has a width or
    // height of 0.
    //            // This indicates that there is no intersection between the source image and the
    // canvas,
    //            // or the intersection is smaller than one pixel.
    //        }
    catch (Throwable t) {
      String reason = WWUtil.extractExceptionReason(t);
      Logging.logger().log(java.util.logging.Level.SEVERE, reason, t);
    } finally {
      // Restore the previous clip, composite, and transform.
      try {
        if (null != g2d) {
          if (null != prevClip) g2d.setClip(prevClip);

          if (null != prevComposite) g2d.setComposite(prevComposite);

          if (null != prevInterpolation)
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, prevInterpolation);

          if (null != prevAntialiasing)
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, prevAntialiasing);
        }
      } catch (Throwable t) {
        Logging.logger().log(java.util.logging.Level.FINEST, WWUtil.extractExceptionReason(t), t);
      }
    }
  }
Пример #6
0
  public void paint(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    // for antialising geometric shapes
    g2d.addRenderingHints(
        new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
    // for antialiasing text
    g2d.setRenderingHint(
        RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

    g.drawImage(this.boardImage, 0, 0, null);

    if (this.drawGrid) {
      for (int x = 0; x < 24; x++) {
        for (int y = 0; y < 29; y++) {
          g.setColor(Color.RED);
          g.drawRect(
              (int) ((x * GUI.xSize) + GUI.xOffset),
              (int) ((y * GUI.ySize) + GUI.yOffset),
              (int) GUI.xSize,
              (int) GUI.ySize);
        }
      }
    }

    if (ui.chooseMovementsMode) {
      for (int x = 0; x < 24; x++) {
        for (int y = 0; y < 29; y++) {
          if (ui.moveables[x][y] == 1) g.setColor(new Color(0, 255, 0, 60));
          else if (ui.moveables[x][y] == 2) g.setColor(new Color(0, 0, 255, 80));
          else continue;

          g.fillRect(
              (int) Math.ceil((x * GUI.xSize) + GUI.xOffset),
              (int) Math.ceil((y * GUI.ySize) + GUI.yOffset),
              (int) Math.ceil(GUI.xSize),
              (int) Math.ceil(GUI.ySize));
        }
      }
    }

    for (Character c : Character.characters) {
      System.out.printf("%d %d\n", c.X, c.Y);
      Color targetColour = Color.BLACK;

      /*
       * new Character("Kasandra Scarlet", 18, 28),
      new Character("Jack Mustard", 7, 28),
      new Character("Diane White", 0, 19),
      new Character("Jacob Green", 0, 9),
      new Character("Eleanor Peacock", 20, 0),
      new Character("Victor Plum", 6, 0)
      */

      if (c == Character.characters[0]) targetColour = scarletColor;
      else if (c == Character.characters[1]) targetColour = mustardColor;
      else if (c == Character.characters[2]) targetColour = whiteColor;
      else if (c == Character.characters[3]) targetColour = greenColor;
      else if (c == Character.characters[4]) targetColour = peacockColor;
      else if (c == Character.characters[5]) targetColour = plumColor;

      g.setColor(targetColour);

      g.fillOval(
          GUI.getCoordFromBoardX(c.X) + 2,
          GUI.getCoordFromBoardY(c.Y) + 2,
          (int) (GUI.xSize - 4),
          (int) (GUI.ySize - 4));
      g.setColor(Color.BLACK);
      g.drawOval(
          GUI.getCoordFromBoardX(c.X) + 2,
          GUI.getCoordFromBoardY(c.Y) + 2,
          (int) (GUI.xSize - 4),
          (int) (GUI.ySize - 4));
    }
  }
Пример #7
0
  public void analyze(boolean doit) {

    float min = Float.POSITIVE_INFINITY;
    float max = Float.NEGATIVE_INFINITY;
    for (int k = 0; k < size; k++) {
      //    	System.out.println(f[k]);
      /*
       * if (f[k] == Float.NaN) { System.out.println("NaN at k= "+k);
       * f[k] = 0f; }
       */
      if (Float.isNaN(f[k])) {
        System.out.println("NaN at k= " + k);
        f[k] = 0f;
        continue;
      }
      if (Float.isInfinite(f[k])) {
        if (f[k] < 0) {
          System.out.println("-Infinity at k= " + k);
          f[k] = 0f; // -1000f;
        } else {
          System.out.println("+Infinity at k= " + k);
          f[k] = 0f; // +1000f;
        }
        continue;
      }
      // System.out.print(k +"="+f[k]+ ", ");
      min = Math.min(min, f[k]);
      max = Math.max(max, f[k]);
    }

    int N = 256;
    float[] histogram = new float[N];

    for (int k = 0; k < size; k++) {
      int level = (int) (0.999f * (float) N * (f[k] - min) / (max - min));
      try {
        histogram[level]++;
      } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("ArrayIndexOutOfBoundsException in ScalarImage.analyze(double) [A].");
      }
    }

    float[] cumulative = new float[N];
    if (histogram[0] > 0) {
      if (doit) {
        cumulative[0] = histogram[0];
      } else {
        cumulative[0] = 1; // histogram[0];
      }
    }
    for (int i = 1; i < N; i++) {
      if (histogram[i] > 0) {
        if (doit) {
          cumulative[i] = cumulative[i - 1] + histogram[i];
        } else {
          cumulative[i] = cumulative[i - 1] + 1; // histogram[i];
        }
      } else {
        cumulative[i] = cumulative[i - 1];
      }
    }

    /*		for(int k=0; k<size; k++) {
    			int level = (int) ( 0.999f*(float)N*(f[k]-min)/(max-min) );
    			try {
    				f[k]=(cumulative[level]-cumulative[0])/(cumulative[N-1]-cumulative[0]);
    			} catch( ArrayIndexOutOfBoundsException e) {
    				System.out.println("ArrayIndexOutOfBoundsException in ScalarImage.analyze(double) [B].");
    			}
    		}
    */
    for (int k = 0; k < size; k++) {
      float x, x1, x2, f1, f2;
      try {
        x = Math.abs((f[k] - min) / (max - min));
        x1 = (float) Math.floor((float) (N - 1) * x * 0.999f) / (float) (N - 1);
        x2 = (float) Math.ceil((float) (N - 1) * x * 0.999f) / (float) (N - 1);
        f1 =
            (cumulative[(int) Math.floor((float) (N - 1) * x * 0.999f)] - cumulative[0])
                / (cumulative[N - 1] - cumulative[0]);
        f2 =
            (cumulative[(int) Math.ceil((float) (N - 1) * x * 0.999f)] - cumulative[0])
                / (cumulative[N - 1] - cumulative[0]);
        f[k] = (f2 - f1) * (x - x1) / (x2 - x1) + f1;
      } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println(
            "ArrayIndexOutOfBoundsException in ScalarImage.analyze(double) [C]. " + e.getMessage());
      }
    }

    return;

    /*
    		double offset = 0. - min;
    		if ((max - min) != 0f) {
    			scale /= (max - min);
    			offset *= scale;
    			rescale(scale, offset);
    		}
    		System.out.println("Normalizing using: min= " + min + " max= " + max
    				+ ", through scaleAdd(" + scale + ", " + offset + ").");
    		min = 1000f;
    		max = -1000f;
    		for (int k = 0; k < size; k++) {
    			if (Float.isNaN(f[k])) {
    				System.out.println("NaN at k= " + k + " after normalization.");
    				f[k] = 0f;
    				continue;
    			}
    			min = Math.min(min, f[k]);
    			max = Math.max(max, f[k]);
    		}
    		System.out.println("After normalization: min= " + min + " max= " + max);
    */
  }
 /**
  * Gets a list of Point2D objects that lie within pixels in a rectangle and along a line.
  *
  * @param searchRect the rectangle
  * @param x0 the x-component of a point on the line
  * @param y0 the y-component of a point on the line
  * @param slope the slope of the line
  * @return a list of Point2D
  */
 public ArrayList<Point2D> getSearchPoints(
     Rectangle searchRect, double x0, double y0, double theta) {
   double slope = -Math.tan(theta);
   // create line to search along
   Line2D line = new Line2D.Double();
   if (slope > LARGE_NUMBER) {
     line.setLine(x0, y0, x0, y0 + 1);
   } else if (slope < 1 / LARGE_NUMBER) {
     line.setLine(x0, y0, x0 + 1, y0);
   } else {
     line.setLine(x0, y0, x0 + 1, y0 + slope);
   }
   // create intersection points (to set line ends)
   Point2D p1 = new Point2D.Double();
   Point2D p2 = new Point2D.Double(Double.NaN, Double.NaN);
   Point2D p = p1;
   boolean foundBoth = false;
   double d = searchRect.x;
   Object[] data = getDistanceAndPointAtX(line, d);
   if (data != null) {
     p.setLocation((Point2D) data[1]);
     if (p.getY() >= searchRect.y && p.getY() <= searchRect.y + searchRect.height) {
       // line end is left edge
       p = p2;
     }
   }
   d += searchRect.width;
   data = getDistanceAndPointAtX(line, d);
   if (data != null) {
     p.setLocation((Point2D) data[1]);
     if (p.getY() >= searchRect.y && p.getY() <= searchRect.y + searchRect.height) {
       // line end is right edge
       if (p == p1) p = p2;
       else foundBoth = true;
     }
   }
   if (!foundBoth) {
     d = searchRect.y;
     data = getDistanceAndPointAtY(line, d);
     if (data != null) {
       p.setLocation((Point2D) data[1]);
       if (p.getX() >= searchRect.x && p.getX() <= searchRect.x + searchRect.width) {
         // line end is top edge
         if (p == p1) p = p2;
         else if (!p1.equals(p2)) foundBoth = true;
       }
     }
   }
   if (!foundBoth) {
     d += searchRect.height;
     data = getDistanceAndPointAtY(line, d);
     if (data != null) {
       p.setLocation((Point2D) data[1]);
       if (p.getX() >= searchRect.x && p.getX() <= searchRect.x + searchRect.width) {
         // line end is bottom edge
         if (p == p2 && !p1.equals(p2)) foundBoth = true;
       }
     }
   }
   // if both line ends have been found, use line to find pixels to search
   if (foundBoth) {
     // set line ends to intersections
     line.setLine(p1, p2);
     if (p1.getX() > p2.getX()) {
       line.setLine(p2, p1);
     }
     // find pixel intersections that fall along the line
     int xMin = (int) Math.ceil(Math.min(p1.getX(), p2.getX()));
     int xMax = (int) Math.floor(Math.max(p1.getX(), p2.getX()));
     int yMin = (int) Math.ceil(Math.min(p1.getY(), p2.getY()));
     int yMax = (int) Math.floor(Math.max(p1.getY(), p2.getY()));
     // collect intersections in TreeMap sorted by position along line
     TreeMap<Double, Point2D> intersections = new TreeMap<Double, Point2D>();
     for (int x = xMin; x <= xMax; x++) {
       Object[] next = getDistanceAndPointAtX(line, x);
       intersections.put((Double) next[0], (Point2D) next[1]);
     }
     for (int y = yMin; y <= yMax; y++) {
       Object[] next = getDistanceAndPointAtY(line, y);
       intersections.put((Double) next[0], (Point2D) next[1]);
     }
     p = null;
     // create array of search points that are midway between intersections
     ArrayList<Point2D> searchPts = new ArrayList<Point2D>();
     for (Double key : intersections.keySet()) {
       Point2D next = intersections.get(key);
       if (p != null) {
         double x = (p.getX() + next.getX()) / 2 - searchRect.x;
         double y = (p.getY() + next.getY()) / 2 - searchRect.y;
         p.setLocation(x, y);
         searchPts.add(p);
       }
       p = next;
     }
     return searchPts;
   }
   return null;
 }