List of usage examples for java.awt.image WritableRaster setPixel
public void setPixel(int x, int y, double[] dArray)
From source file:tilt.image.Picture.java
/** * Convert from greyscale to twotone (black and white) * Adapted from OCRopus//from w ww . ja v a 2s. c o m * Copyright 2006-2008 Deutsches Forschungszentrum fuer Kuenstliche * Intelligenz or its licensors, as applicable. * http://ocropus.googlecode.com/svn/trunk/ocr-binarize/ocr-binarize-sauvola.cc * @throws Exception */ void convertToTwoTone() throws ImageException { try { int MAXVAL = 256; double k = 0.34; if (greyscale == null) convertToGreyscale(); BufferedImage grey = ImageIO.read(greyscale); WritableRaster grey_image = grey.getRaster(); WritableRaster bin_image = grey.copyData(null); int square = (int) Math.floor(grey_image.getWidth() * 0.025); if (square == 0) square = Math.min(20, grey_image.getWidth()); if (square > grey_image.getHeight()) square = grey_image.getHeight(); int whalf = square >> 1; if (whalf == 0) throw new Exception("whalf==0!"); int image_width = grey_image.getWidth(); int image_height = grey_image.getHeight(); // Calculate the integral image, and integral of the squared image // original algorithm ate up too much memory, use floats for longs float[][] integral_image = new float[image_width][image_height]; float[][] rowsum_image = new float[image_width][image_height]; float[][] integral_sqimg = new float[image_width][image_height]; float[][] rowsum_sqimg = new float[image_width][image_height]; int xmin, ymin, xmax, ymax; double diagsum, idiagsum, diff, sqdiagsum, sqidiagsum, sqdiff, area; double mean, std, threshold; // for get/setPixel int[] iArray = new int[1]; int[] oArray = new int[1]; for (int j = 0; j < image_height; j++) { grey_image.getPixel(0, j, iArray); rowsum_image[0][j] = iArray[0]; rowsum_sqimg[0][j] = iArray[0] * iArray[0]; } for (int i = 1; i < image_width; i++) { for (int j = 0; j < image_height; j++) { grey_image.getPixel(i, j, iArray); rowsum_image[i][j] = rowsum_image[i - 1][j] + iArray[0]; rowsum_sqimg[i][j] = rowsum_sqimg[i - 1][j] + iArray[0] * iArray[0]; } } for (int i = 0; i < image_width; i++) { integral_image[i][0] = rowsum_image[i][0]; integral_sqimg[i][0] = rowsum_sqimg[i][0]; } for (int i = 0; i < image_width; i++) { for (int j = 1; j < image_height; j++) { integral_image[i][j] = integral_image[i][j - 1] + rowsum_image[i][j]; integral_sqimg[i][j] = integral_sqimg[i][j - 1] + rowsum_sqimg[i][j]; } } // compute mean and std.dev. using the integral image for (int i = 0; i < image_width; i++) { for (int j = 0; j < image_height; j++) { xmin = Math.max(0, i - whalf); ymin = Math.max(0, j - whalf); xmax = Math.min(image_width - 1, i + whalf); ymax = Math.min(image_height - 1, j + whalf); area = (xmax - xmin + 1) * (ymax - ymin + 1); grey_image.getPixel(i, j, iArray); // area can't be 0 here if (area == 0) throw new Exception("area can't be 0 here!"); if (xmin == 0 && ymin == 0) { // Point at origin diff = integral_image[xmax][ymax]; sqdiff = integral_sqimg[xmax][ymax]; } else if (xmin == 0 && ymin != 0) { // first column diff = integral_image[xmax][ymax] - integral_image[xmax][ymin - 1]; sqdiff = integral_sqimg[xmax][ymax] - integral_sqimg[xmax][ymin - 1]; } else if (xmin != 0 && ymin == 0) { // first row diff = integral_image[xmax][ymax] - integral_image[xmin - 1][ymax]; sqdiff = integral_sqimg[xmax][ymax] - integral_sqimg[xmin - 1][ymax]; } else { // rest of the image diagsum = integral_image[xmax][ymax] + integral_image[xmin - 1][ymin - 1]; idiagsum = integral_image[xmax][ymin - 1] + integral_image[xmin - 1][ymax]; diff = diagsum - idiagsum; sqdiagsum = integral_sqimg[xmax][ymax] + integral_sqimg[xmin - 1][ymin - 1]; sqidiagsum = integral_sqimg[xmax][ymin - 1] + integral_sqimg[xmin - 1][ymax]; sqdiff = sqdiagsum - sqidiagsum; } mean = diff / area; std = Math.sqrt((sqdiff - diff * diff / area) / (area - 1)); threshold = mean * (1 + k * ((std / 128) - 1)); if (iArray[0] < threshold) oArray[0] = 0; else oArray[0] = MAXVAL - 1; bin_image.setPixel(i, j, oArray); } } twotone = File.createTempFile(PictureRegistry.PREFIX, PictureRegistry.SUFFIX); grey.setData(bin_image); ImageIO.write(grey, "png", twotone); } catch (Exception e) { throw new ImageException(e); } }
From source file:org.photovault.dcraw.AHDInterpolateOp.java
/** * Conpute a rectangle of destination image using AHD interpolation * @param img Array of soruce images (containing just one image in this case * @param dst Raster for the results/* w ww . j a v a 2s.c om*/ * @param area Area of dst that needs to be computed */ private void computeRectAHD(PlanarImage[] img, WritableRaster dst, Rectangle area) { log.debug("entry: computeAHD " + area); long entryTime = System.currentTimeMillis(); // RandomIterFactory.create( img[0], area); int minx = Math.max((int) area.getMinX() - 3, 0); int miny = Math.max((int) area.getMinY() - 3, 0); int maxx = Math.min((int) area.getMaxX() + 3, getWidth() - 1); int maxy = Math.min((int) area.getMaxY() + 3, getHeight() - 1); Rectangle enlargedArea = new Rectangle(minx, miny, maxx - minx + 1, maxy - miny + 1); int[][][][] rgb = new int[2][(int) enlargedArea.getWidth()][(int) enlargedArea.getHeight()][3]; int[][][][] lab = new int[2][(int) enlargedArea.getWidth()][(int) enlargedArea.getHeight()][3]; byte[][][] homo = new byte[2][(int) enlargedArea.getWidth()][(int) enlargedArea.getHeight()]; RandomIter riter = RandomIterFactory.create(img[0], enlargedArea); double xyz[] = new double[3]; // Copy the data to temp array for (int y = 0; y < maxy - miny; y++) { for (int x = 0; x < maxx - minx; x++) { int color = fc(y + miny, x + minx); if (color == 3) color = 1; rgb[0][x][y][color] = rgb[1][x][y][color] = (int) (mult[color] * riter.getSample(x + minx, y + miny, 0)); } } // Interpolate green for (int y = 2; y < maxy - miny - 2; y++) { int firstColor = fc(y + miny, minx + 3); int startCol = minx + 3 - (firstColor % 2); for (int x = startCol - minx; x < maxx - minx - 2; x += 2) { int c = fc(y + miny, x + minx); if (c == 3) { c = 1; } int tc = rgb[0][x][y][c]; int eg = rgb[0][x - 1][y][1]; int wg = rgb[0][x + 1][y][1]; int sg = rgb[0][x][y + 1][1]; int ng = rgb[0][x][y - 1][1]; int ec = rgb[0][x - 2][y][c]; int wc = rgb[0][x + 2][y][c]; int sc = rgb[0][x][y + 2][c]; int nc = rgb[0][x][y - 2][c]; // Horizonally int green = 2 * (wg + tc + eg) - (wc + ec); green >>= 2; if (green < 0) green = 0; rgb[0][x][y][1] = green; // Vertically green = 2 * (ng + tc + sg) - (nc + sc); green >>= 2; if (green < 0) green = 0; rgb[1][x][y][1] = green; } } // Interpolate R & B for (int dir = 0; dir < 2; dir++) { for (int y = 3; y < maxy - miny - 3; y++) { for (int x = 3; x < maxx - minx - 3; x++) { int color = fc(y + miny, x + minx); if (color == 1 || color == 3) { // We need to interpolate both red and blue int c = fc(y + 1 + miny, x + minx); int tg = rgb[dir][x][y][1]; int ng = rgb[dir][x][y - 1][1]; int sg = rgb[dir][x][y + 1][1]; int eg = rgb[dir][x + 1][y][1]; int wg = rgb[dir][x - 1][y][1]; int nc = rgb[dir][x][y - 1][c]; int sc = rgb[dir][x][y + 1][c]; int wo = rgb[dir][x - 1][y][2 - c]; int eo = rgb[dir][x + 1][y][2 - c]; int val = tg + ((wo + eo - ng - sg) >> 1); if (val < 0) val = 0; rgb[dir][x][y][2 - c] = val; val = tg + ((nc + sc - ng - sg) >> 1); if (val < 0) val = 0; rgb[dir][x][y][c] = val; } else { /* This pixel is either red or blue so only one of those needs to be interpolated */ int c = 2 - color; int tg = rgb[dir][x][y][1]; int nwg = rgb[dir][x - 1][y - 1][1]; int seg = rgb[dir][x + 1][y + 1][1]; int swg = rgb[dir][x - 1][y + 1][1]; int neg = rgb[dir][x + 1][y - 1][1]; int nwc = rgb[dir][x - 1][y - 1][c]; int nec = rgb[dir][x + 1][y - 1][c]; int swc = rgb[dir][x - 1][y + 1][c]; int sec = rgb[dir][x + 1][y + 1][c]; int val = tg + ((nwc + nec + sec + swc - nwg - neg - swg - seg) >> 2); if (val < 0) val = 0; rgb[dir][x][y][c] = val; } xyz[0] = xyz[1] = xyz[2] = 0.5; // Convert to cielab for (int i = 0; i < 3; i++) { xyz[0] += xyz_cam[0][i] * rgb[dir][x][y][i]; xyz[1] += xyz_cam[1][i] * rgb[dir][x][y][i]; xyz[2] += xyz_cam[2][i] * rgb[dir][x][y][i]; } xyz[0] = cbrt[Math.max(0, (int) Math.min(xyz[0], 65535.0))]; xyz[1] = cbrt[Math.max(0, (int) Math.min(xyz[1], 65535.0))]; xyz[2] = cbrt[Math.max(0, (int) Math.min(xyz[2], 65535.0))]; lab[dir][x][y][0] = Math.max(0, (int) (64.0 * (116.0 * xyz[1] - 16.0))); lab[dir][x][y][1] = 0x8000 + 10 * (int) (64.0 * 500.0 * (xyz[0] - xyz[1])); lab[dir][x][y][2] = 0x8000 + 10 * (int) (64.0 * 200.0 * (xyz[1] - xyz[2])); } } } // Calculate the homogeneity maps int ldiff[][] = new int[2][4]; int abdiff[][] = new int[2][4]; int dx[] = { -1, 1, 0, 0 }; int dy[] = { 0, 0, -1, 1 }; for (int y = 2; y < maxy - miny - 2; y++) { for (int x = 2; x < maxx - minx - 2; x++) { for (int d = 0; d < 2; d++) { for (int i = 0; i < 4; i++) { ldiff[d][i] = Math.abs(lab[d][x][y][0] - lab[d][x + dx[i]][y + dy[i]][0]); int da = lab[d][x][y][1] - lab[d][x + dx[i]][y + dy[i]][1]; int db = lab[d][x][y][1] - lab[d][x + dx[i]][y + dy[i]][1]; abdiff[d][i] = da * da + db * db; } } int leps = Math.min(Math.max(ldiff[0][0], ldiff[0][1]), Math.max(ldiff[1][2], ldiff[1][3])); int abeps = Math.min(Math.max(abdiff[0][0], abdiff[0][1]), Math.max(abdiff[1][2], abdiff[1][3])); for (int d = 0; d < 2; d++) { for (int i = 0; i < 4; i++) { if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps) { homo[d][x][y]++; } } } } } int dstMinx = Math.max((int) area.getMinX(), 5); int dstMiny = Math.max((int) area.getMinY(), 5); int dstMaxy = Math.min((int) area.getMaxY(), getHeight() - 5); int dstMaxx = Math.min((int) area.getMaxX(), getWidth() - 5); for (int row = dstMiny; row < dstMaxy; row++) { for (int col = dstMinx; col < dstMaxx; col++) { int hm0 = 0, hm1 = 0; for (int i = row - miny - 1; i <= row - miny + 1; i++) { for (int j = col - minx - 1; j <= col - minx + 1; j++) { hm0 += homo[0][j][i]; hm1 += homo[1][j][i]; } } if (hm0 < hm1) { dst.setPixel(col, row, rgb[1][col - minx][row - miny]); } else if (hm0 > hm1) { dst.setPixel(col, row, rgb[0][col - minx][row - miny]); } else { for (int i = 0; i < 3; i++) { rgb[0][col - minx][row - miny][i] += rgb[1][col - minx][row - miny][i]; rgb[0][col - minx][row - miny][i] /= 2; } dst.setPixel(col, row, rgb[0][col - minx][row - miny]); } } } long dur = System.currentTimeMillis() - entryTime; log.debug("exit: computeRectAHD in " + dur + "ms"); }