/** * 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); } }
/** * 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); }
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)); }
/* * 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; }
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); } } }
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)); } }
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; }