@Override public void applyInPlace(FastBitmap fastBitmap) { int size = fastBitmap.getSize(); if (fastBitmap.isGrayscale()) { CalculateMap(inGray, outGray, mapGray); for (int x = 0; x < size; x++) { fastBitmap.setGray(x, mapGray[fastBitmap.getGray(x)]); } } else { CalculateMap(inRed, outRed, mapRed); CalculateMap(inGreen, outGreen, mapGreen); CalculateMap(inBlue, outBlue, mapBlue); for (int x = 0; x < size; x++) { int r = mapRed[fastBitmap.getRed(x)]; int g = mapGreen[fastBitmap.getGreen(x)]; int b = mapBlue[fastBitmap.getBlue(x)]; fastBitmap.setRGB(x, r, g, b); } } }
/** * Extract blob. * * @param id ID. * @param fastBitmap Image to be processed. * @return Image with the extracted blob. */ public FastBitmap Extract(int id, FastBitmap fastBitmap) { // Check if blobs list is null. if (this.blobs == null) this.blobs = new BlobDetection().ProcessImage(fastBitmap); FastBitmap image; if (fastBitmap.isGrayscale()) { image = new FastBitmap( fastBitmap.getWidth(), fastBitmap.getHeight(), FastBitmap.ColorSpace.Grayscale); for (IntPoint p : blobs.get(id).getPoints()) { image.setGray(p.x, p.y, fastBitmap.getGray(p.x, p.y)); } } else { image = new FastBitmap(fastBitmap.getWidth(), fastBitmap.getHeight(), FastBitmap.ColorSpace.RGB); for (IntPoint p : blobs.get(id).getPoints()) { image.setRed(p.x, p.y, fastBitmap.getRed(p.x, p.y)); image.setGreen(p.x, p.y, fastBitmap.getGreen(p.x, p.y)); image.setBlue(p.x, p.y, fastBitmap.getBlue(p.x, p.y)); } } return image; }
/** * Computes histograms. * * @param fastBitmap Image. */ private void ProcessImage(FastBitmap fastBitmap) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); if (fastBitmap.isGrayscale()) { int[] g = new int[width]; for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { g[y] += fastBitmap.getGray(x, y); } } gray = new Histogram(g); } if (fastBitmap.isRGB()) { int[] r = new int[width]; int[] g = new int[width]; int[] b = new int[width]; for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { r[y] += fastBitmap.getRed(x, y); g[y] += fastBitmap.getGreen(x, y); b[y] += fastBitmap.getBlue(x, y); } } red = new Histogram(r); green = new Histogram(g); blue = new Histogram(b); } }
@Override public void applyInPlace(FastBitmap fastBitmap) { if (fastBitmap.isGrayscale()) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); double oldIradius = (double) (height - 1) / 2; double oldJradius = (double) (width - 1) / 2; CalculateNewSize(fastBitmap); FastBitmap destinationData = new FastBitmap(newWidth, newHeight, FastBitmap.ColorSpace.Grayscale); // get destination image size double newIradius = (double) (newHeight - 1) / 2; double newJradius = (double) (newWidth - 1) / 2; // angle's sine and cosine double angleRad = -angle * Math.PI / 180; double angleCos = Math.cos(angleRad); double angleSin = Math.sin(angleRad); // destination pixel's coordinate relative to image center double ci, cj; // coordinates of source points and cooefficiens double oi, oj, di, dj, k1, k2; int oi1, oj1, oi2, oj2; // width and height decreased by 1 int imax = height - 1; int jmax = width - 1; ci = -newIradius; for (int i = 0; i < newHeight; i++) { cj = -newJradius; for (int j = 0; j < newWidth; j++) { // coordinate of the nearest point oi = angleCos * ci + angleSin * cj + oldIradius; oj = -angleSin * ci + angleCos * cj + oldJradius; oi1 = (int) oi; oj1 = (int) oj; // validate source pixel's coordinates if ((oi1 < 0) || (oj1 < 0) || (oi1 >= height) || (oj1 >= width)) { // fill destination image with filler destinationData.setGray(i, j, fillGray); } else { di = oi - (double) oi1; dj = oj - (double) oj1; // initial pixel value int g = 0; for (int n = -1; n < 3; n++) { // get Y cooefficient k1 = Interpolation.BiCubicKernel(dj - (double) n); oj2 = oj1 + n; if (oj2 < 0) oj2 = 0; if (oj2 > jmax) oj2 = jmax; for (int m = -1; m < 3; m++) { // get X cooefficient k2 = k1 * Interpolation.BiCubicKernel((double) m - di); oi2 = oi1 + m; if (oi2 < 0) oi2 = 0; if (oi2 > imax) oi2 = imax; g += k2 * fastBitmap.getGray(oi2, oj2); } } destinationData.setGray(i, j, Math.max(0, Math.min(255, g))); } cj++; } ci++; } fastBitmap.setImage(destinationData); destinationData.recycle(); } else if (fastBitmap.isRGB()) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); double oldIradius = (double) (height - 1) / 2; double oldJradius = (double) (width - 1) / 2; CalculateNewSize(fastBitmap); FastBitmap destinationData = new FastBitmap(newWidth, newHeight, FastBitmap.ColorSpace.RGB); // get destination image size double newIradius = (double) (newHeight - 1) / 2; double newJradius = (double) (newWidth - 1) / 2; // angle's sine and cosine double angleRad = -angle * Math.PI / 180; double angleCos = Math.cos(angleRad); double angleSin = Math.sin(angleRad); // destination pixel's coordinate relative to image center double ci, cj; // coordinates of source points and cooefficiens double oi, oj, di, dj, k1, k2; int oi1, oj1, oi2, oj2; // width and height decreased by 1 int imax = height - 1; int jmax = width - 1; ci = -newIradius; for (int i = 0; i < newHeight; i++) { cj = -newJradius; for (int j = 0; j < newWidth; j++) { // coordinate of the nearest point oi = angleCos * ci + angleSin * cj + oldIradius; oj = -angleSin * ci + angleCos * cj + oldJradius; oi1 = (int) oi; oj1 = (int) oj; // validate source pixel's coordinates if ((oi < 0) || (oj < 0) || (oi >= height) || (oj >= width)) { // fill destination image with filler destinationData.setRGB(i, j, fillRed, fillGreen, fillBlue); } else { di = oi - (double) oi1; dj = oj - (double) oj1; // initial pixel value int r = 0; int g = 0; int b = 0; for (int n = -1; n < 3; n++) { // get Y cooefficient k1 = Interpolation.BiCubicKernel(dj - (double) n); oj2 = oj1 + n; if (oj2 < 0) oj2 = 0; if (oj2 > jmax) oj2 = jmax; for (int m = -1; m < 3; m++) { // get X cooefficient k2 = k1 * Interpolation.BiCubicKernel((double) m - di); oi2 = oi1 + m; if (oi2 < 0) oi2 = 0; if (oi2 > imax) oi2 = imax; r += k2 * fastBitmap.getRed(oi2, oj2); g += k2 * fastBitmap.getGreen(oi2, oj2); b += k2 * fastBitmap.getBlue(oi2, oj2); } } r = Math.max(0, Math.min(255, r)); g = Math.max(0, Math.min(255, g)); b = Math.max(0, Math.min(255, b)); destinationData.setRGB(i, j, r, g, b); } cj++; } ci++; } fastBitmap.setImage(destinationData); destinationData.recycle(); } }
@Override public void applyInPlace(FastBitmap fastBitmap) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); int Xline, Yline; int lines = CalcLines(radius); int maxArray = lines * lines; int c; FastBitmap copy = new FastBitmap(fastBitmap); if (fastBitmap.isGrayscale()) { int[] avgL = new int[maxArray]; for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { c = 0; for (int i = 0; i < lines; i++) { Xline = x + (i - radius); for (int j = 0; j < lines; j++) { Yline = y + (j - radius); if ((Xline >= 0) && (Xline < height) && (Yline >= 0) && (Yline < width)) { avgL[c] = copy.getGray(Xline, Yline); } else { avgL[c] = copy.getGray(x, y); } c++; } } Arrays.sort(avgL); // alpha trimmed mean double mean = 0; for (int i = t; i < c - t; i++) { mean += avgL[i]; } fastBitmap.setGray(x, y, (int) (mean / (avgL.length - 2 * t))); } } } else if (fastBitmap.isRGB()) { int[] avgR = new int[maxArray]; int[] avgG = new int[maxArray]; int[] avgB = new int[maxArray]; for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { c = 0; for (int i = 0; i < lines; i++) { Xline = x + (i - radius); for (int j = 0; j < lines; j++) { Yline = y + (j - radius); if ((Xline >= 0) && (Xline < height) && (Yline >= 0) && (Yline < width)) { avgR[c] = copy.getRed(Xline, Yline); avgG[c] = copy.getGreen(Xline, Yline); avgB[c] = copy.getBlue(Xline, Yline); } else { avgR[c] = copy.getRed(x, y); avgG[c] = copy.getGreen(x, y); avgB[c] = copy.getBlue(x, y); } c++; } } Arrays.sort(avgR); Arrays.sort(avgG); Arrays.sort(avgB); // alpha trimmed mean double meanR = 0, meanG = 0, meanB = 0; for (int i = t; i < c - t; i++) { meanR += avgR[i]; meanG += avgG[i]; meanB += avgB[i]; } meanR /= (avgR.length - 2 * t); meanG /= (avgG.length - 2 * t); meanB /= (avgB.length - 2 * t); fastBitmap.setRGB(x, y, (int) meanR, (int) meanG, (int) meanB); } } } }
/** * Compute GLRLM. * * @param fastBitmap Image to be processed. * @return GLRLM. */ public double[][] Compute(FastBitmap fastBitmap) { int maxGray = 255; if (autoGray) maxGray = ImageStatistics.Maximum(fastBitmap); int height = fastBitmap.getHeight(); int width = fastBitmap.getWidth(); double[][] runMatrix = new double[maxGray + 1][width + 1]; switch (degree) { case Degree_0: for (int i = 0; i < height; i++) { int runs = 1; for (int j = 1; j < width; j++) { int g1 = fastBitmap.getGray(i, j - 1); int g2 = fastBitmap.getGray(i, j); if (g1 == g2) { runs++; } else { runMatrix[g1][runs]++; numPrimitives++; runs = 1; } if ((g1 == g2) && (j == width - 1)) { runMatrix[g1][runs]++; } if ((g1 != g2) && (j == width - 1)) { runMatrix[g2][1]++; } } } break; case Degree_45: // Compute I(0,0) and I(height,width) runMatrix[0][1]++; runMatrix[height - 1][width - 1]++; // Compute height for (int i = 1; i < height; i++) { int runs = 1; int steps = i; for (int j = 0; j < steps; j++) { int g1 = fastBitmap.getGray(i - j, j); int g2 = fastBitmap.getGray(i - j - 1, j + 1); if (g1 == g2) { runs++; } else { runMatrix[g1][runs]++; numPrimitives++; runs = 1; } if ((g1 == g2) && (j == steps - 1)) { runMatrix[g1][runs]++; } if ((g1 != g2) && (j == steps - 1)) { runMatrix[g2][1]++; } } } // Compute width for (int j = 1; j < width - 1; j++) { int runs = 1; int steps = height - j; for (int i = 1; i < steps; i++) { int g1 = fastBitmap.getGray(height - i, j + i - 1); int g2 = fastBitmap.getGray(height - i - 1, j + i); if (g1 == g2) { runs++; } else { runMatrix[g1][runs]++; numPrimitives++; runs = 1; } if ((g1 == g2) && (i == steps - 1)) { runMatrix[g1][runs]++; } if ((g1 != g2) && (i == steps - 1)) { runMatrix[g2][1]++; } } } break; case Degree_90: for (int j = 0; j < width; j++) { int runs = 1; for (int i = 0; i < height - 1; i++) { int g1 = fastBitmap.getGray(height - i - 1, j); int g2 = fastBitmap.getGray(height - i - 2, j); if (g1 == g2) { runs++; } else { runMatrix[g1][runs]++; numPrimitives++; runs = 1; } if ((g1 == g2) && (i == height - 2)) { runMatrix[g1][runs]++; } if ((g1 != g2) && (i == height - 2)) { runMatrix[g2][1]++; } } } break; case Degree_135: // Compute I(0,width) and I(height,0) runMatrix[0][width - 1]++; runMatrix[height - 1][0]++; // Compute height for (int i = 1; i < width; i++) { int runs = 1; int steps = i; int w = width - 1; for (int j = 0; j < steps; j++) { int g1 = fastBitmap.getGray(i - j, w); int g2 = fastBitmap.getGray(i - j - 1, --w); if (g1 == g2) { runs++; } else { runMatrix[g1][runs]++; numPrimitives++; runs = 1; } if ((g1 == g2) && (j == steps - 1)) { runMatrix[g1][runs]++; } if ((g1 != g2) && (j == steps - 1)) { runMatrix[g2][1]++; } } } // Compute width for (int j = 1; j < width - 1; j++) { int runs = 1; int steps = height - j; int w = width - 1 - j; for (int i = 1; i < steps; i++) { int g1 = fastBitmap.getGray(height - i, w); int g2 = fastBitmap.getGray(height - i - 1, --w); if (g1 == g2) { runs++; } else { runMatrix[g1][runs]++; numPrimitives++; runs = 1; } if ((g1 == g2) && (i == steps - 1)) { runMatrix[g1][runs]++; } if ((g1 != g2) && (i == steps - 1)) { runMatrix[g2][1]++; } } } break; } return runMatrix; }
@Override public void applyInPlace(FastBitmap fastBitmap) { if (fastBitmap.isRGB()) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); LinkedList<IntPoint> examList = new LinkedList(); Color old = new Color(fastBitmap.getRGB(startPoint)); switch (algorithm) { case FourWay: if (!Color.isEqual(old, replace)) { examList.addFirst(new IntPoint(startPoint)); while (examList.size() > 0) { IntPoint p = examList.removeLast(); old = new Color(fastBitmap.getRGB(p)); if (!Color.isEqual(old, replace)) { int x = p.x; int y = p.y; fastBitmap.setRGB(x, y, replace); if (y - 1 > 0) { examList.addFirst(new IntPoint(x, y - 1)); // check west neighbor } if (y + 1 < width) { examList.addFirst(new IntPoint(x, y + 1)); // check east neighbor } if (x + 1 < height) { examList.addFirst(new IntPoint(x + 1, y)); // check south neighbor } if (x - 1 > 0) { examList.addFirst(new IntPoint(x - 1, y)); // check north neighbor } } } } break; case EightWay: if (!Color.isEqual(old, replace)) { examList.addFirst(new IntPoint(startPoint)); while (examList.size() > 0) { IntPoint p = examList.removeFirst(); if (Color.isEqual(old, replace)) { int x = p.x; int y = p.y; fastBitmap.setRGB(x, y, replace); if ((x - 1 > 0) && (y - 1 > 0)) { examList.addFirst(new IntPoint(x - 1, y - 1)); // check north-west neighbor } if (x - 1 > 0) { examList.addFirst(new IntPoint(x - 1, y)); // check north neighbor } if ((x + 1 < height) && (y + 1 < width)) { examList.addFirst(new IntPoint(x + 1, y + 1)); // check north-east neighbor } if (y - 1 > 0) { examList.addFirst(new IntPoint(x, y - 1)); // check west neighbor } if (y + 1 < width) { examList.addFirst(new IntPoint(x, y + 1)); // check east neighbor } if ((x + 1 < height) && (y - 1 > 0)) { examList.addFirst(new IntPoint(x + 1, y - 1)); // check south-west neighbor } if (x + 1 < height) { examList.addFirst(new IntPoint(x + 1, y)); // check south neighbor } if ((x + 1 < height) && (y + 1 < width)) { examList.addFirst(new IntPoint(x + 1, y + 1)); // check south-east neighbor } } } } break; } } else if (fastBitmap.isGrayscale()) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); LinkedList<IntPoint> examList = new LinkedList(); int iGray = fastBitmap.getGray(startPoint); int _gray = gray; int _Gray = _gray; switch (algorithm) { case FourWay: if (iGray != _Gray) { examList.addFirst(new IntPoint(startPoint)); while (examList.size() > 0) { IntPoint p = examList.removeLast(); _gray = fastBitmap.getGray(p.x, p.y); _Gray = _gray; if (_Gray == iGray) { int x = p.x; int y = p.y; fastBitmap.setGray(x, y, gray); if (y - 1 > 0) { examList.addFirst(new IntPoint(x, y - 1)); // check west neighbor } if (y + 1 < width) { examList.addFirst(new IntPoint(x, y + 1)); // check east neighbor } if (x + 1 < height) { examList.addFirst(new IntPoint(x + 1, y)); // check south neighbor } if (x - 1 > 0) { examList.addFirst(new IntPoint(x - 1, y)); // check north neighbor } } } } break; case EightWay: if (iGray != _Gray) { examList.addFirst(new IntPoint(startPoint)); while (examList.size() > 0) { IntPoint p = examList.removeFirst(); _gray = fastBitmap.getGray(p.x, p.y); _Gray = _gray; if (_Gray == iGray) { int x = p.x; int y = p.y; fastBitmap.setGray(x, y, gray); if ((x - 1 > 0) && (y - 1 > 0)) { examList.addFirst(new IntPoint(x - 1, y - 1)); // check north-west neighbor } if (x - 1 > 0) { examList.addFirst(new IntPoint(x - 1, y)); // check north neighbor } if ((x + 1 < height) && (y + 1 < width)) { examList.addFirst(new IntPoint(x + 1, y + 1)); // check north-east neighbor } if (y - 1 > 0) { examList.addFirst(new IntPoint(x, y - 1)); // check west neighbor } if (y + 1 < width) { examList.addFirst(new IntPoint(x, y + 1)); // check east neighbor } if ((x + 1 < height) && (y - 1 > 0)) { examList.addFirst(new IntPoint(x + 1, y - 1)); // check south-west neighbor } if (x + 1 < height) { examList.addFirst(new IntPoint(x + 1, y)); // check south neighbor } if ((x + 1 < height) && (y + 1 < width)) { examList.addFirst(new IntPoint(x + 1, y + 1)); // check south-east neighbor } } } } break; } } else { throw new IllegalArgumentException("Flood fill only works in RGB and grayscale images."); } }
@Override public void applyInPlace(FastBitmap fastBitmap) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); int Xline, Yline; int radiusI = (weight.length - 1) / 2; int radiusJ = (weight[0].length - 1) / 2; int maxArray = calcMax(weight); int c; FastBitmap copy = new FastBitmap(fastBitmap); if (fastBitmap.isGrayscale()) { int[] avgL = new int[maxArray]; int median; for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { c = 0; for (int i = 0; i < weight.length; i++) { Xline = x + (i - radiusI); for (int j = 0; j < weight[0].length; j++) { Yline = y + (j - radiusJ); if ((Xline >= 0) && (Xline < height) && (Yline >= 0) && (Yline < width)) { if (weight[i][j] > 0) { for (int k = 0; k < weight[i][j]; k++) { avgL[c] = copy.getGray(Xline, Yline); c++; } } } } } Arrays.sort(avgL, 0, c); // median median = c / 2; fastBitmap.setGray(x, y, avgL[median]); } } } else if (fastBitmap.isRGB()) { int[] avgR = new int[maxArray]; int[] avgG = new int[maxArray]; int[] avgB = new int[maxArray]; int median; for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { c = 0; for (int i = 0; i < weight.length; i++) { Xline = x + (i - radiusI); for (int j = 0; j < weight[0].length; j++) { Yline = y + (j - radiusJ); if ((Xline >= 0) && (Xline < height) && (Yline >= 0) && (Yline < width)) { if (weight[i][j] > 0) { for (int k = 0; k < weight[i][j]; k++) { avgR[c] = copy.getRed(Xline, Yline); avgG[c] = copy.getGreen(Xline, Yline); avgB[c] = copy.getBlue(Xline, Yline); c++; } } } } } Arrays.sort(avgR, 0, c); Arrays.sort(avgG, 0, c); Arrays.sort(avgB, 0, c); // median median = c / 2; fastBitmap.setRGB(x, y, avgR[median], avgG[median], avgB[median]); } } } }
@Override public void applyInPlace(FastBitmap fastBitmap) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); FastBitmap copy = new FastBitmap(fastBitmap); if (fastBitmap.isGrayscale()) { for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { double mean = 0; double var = 0; int total = 0; for (int i = x - radius; i <= x + radius; i++) { for (int j = y - radius; j <= y + radius; j++) { if (i >= 0 && i < height && j >= 0 && j < width) { mean += copy.getGray(i, j); total++; } } } mean /= total; for (int i = x - radius; i <= x + radius; i++) { for (int j = y - radius; j <= y + radius; j++) { if (i >= 0 && i < height && j >= 0 && j < width) var += Math.pow(copy.getGray(i, j) - mean, 2); } } var /= total - 1; if (var < 0) var = 0; if (var > 255) var = 255; fastBitmap.setGray(x, y, (int) var); } } } if (fastBitmap.isRGB()) { for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { double meanR = 0, meanG = 0, meanB = 0; double varR = 0, varG = 0, varB = 0; int total = 0; for (int i = x - radius; i <= x + radius; i++) { for (int j = y - radius; j <= y + radius; j++) { if (i >= 0 && i < height && j >= 0 && j < width) { meanR += copy.getRed(i, j); meanG += copy.getGreen(i, j); meanB += copy.getBlue(i, j); total++; } } } meanR /= total; meanG /= total; meanB /= total; for (int i = x - radius; i <= x + radius; i++) { for (int j = y - radius; j <= y + radius; j++) { if (i >= 0 && i < height && j >= 0 && j < width) { varR += Math.pow(copy.getRed(i, j) - meanR, 2); varG += Math.pow(copy.getGreen(i, j) - meanG, 2); varB += Math.pow(copy.getBlue(i, j) - meanB, 2); } } } varR /= total - 1; varG /= total - 1; varB /= total - 1; if (varR < 0) varR = 0; if (varG < 0) varG = 0; if (varB < 0) varB = 0; if (varR > 255) varR = 255; if (varG > 255) varG = 255; if (varB > 255) varB = 255; fastBitmap.setRGB(x, y, (int) varR, (int) varG, (int) varB); } } } }