// package nbtool.gui.logviews.images; // import java.awt.image.BufferedImage; // import java.awt.image.Raster; // import java.awt.image.WritableRaster; // import java.util.ArrayList; // import java.util.Vector; // import nbtool.data.Log; // import nbtool.images.YUYV8888image; // import nbtool.util.U; // // TODO better logic when there are more than two detected peaks // // TODO refactor GradientCalculator into a Gradient class // public class PostDetector extends Detector { // YUYV8888image original; // BufferedImage gradient; // BufferedImage yellow; // // BufferedImage field; // BufferedImage post; // double[] rawScores; // double[] processedScores; // ArrayList<Integer> candidates; // public PostDetector(Log log_) { // super(log_); // original = (YUYV8888image) U.imageFromLog(log); // buildGradientImg(); // // StructuringElement cross = new StructuringElement(0); // // MathMorphology mm = new MathMorphology(cross); // // mm.opening(gradient); // buildYellowImg(); // StructuringElement verticalBandOf5Pixels = new StructuringElement(2); // MathMorphology mm = new MathMorphology(verticalBandOf5Pixels); // //mm.opening(yellow); // // buildFieldImg(); // // StructuringElement square = new StructuringElement(4); // // mm.setStructuringElement(square); // // mm.opening(field); // post = GrayscaleLib.and(gradient, yellow); // buildHistogram(); // processHistogram(); // detectPeaks(); // } // private double calculateColorScore(int y, int u, int v) { // FuzzyThreshold sigmaY = new FuzzyThreshold(70, 100); // FuzzyThreshold sigmaU = new FuzzyThreshold(110, 150); // FuzzyThreshold sigmaV = new FuzzyThreshold(125, 150); // double yScore = sigmaY.f((double) y); // double uScore = 1 - sigmaU.f((double) u); // double vScore = sigmaV.f((double) v); // double smallestScore = uScore; // if (yScore < uScore) { // smallestScore = yScore; // } // if (vScore < smallestScore) { // smallestScore = vScore; // } // return smallestScore; // } // private void buildYellowImg() { // BufferedImage yellowImg = new BufferedImage(original.width / 2 - 1, original.height - 1, BufferedImage.TYPE_BYTE_GRAY); // WritableRaster raster = yellowImg.getRaster(); // for (int i = 1; i < original.height - 1; i++) { // for (int j = 1; j < (original.width / 2 - 1); j += 1) { // int[] pixel = new int[1]; // int y = original.yPixelAt(j, i); // int u = original.uPixelAt(j, i); // int v = original.vPixelAt(j, i); // pixel[0] = (int)(255*calculateColorScore(y, u, v)); // raster.setPixel(j-1, i-1, pixel); // } // } // yellow = yellowImg; // } // private double calculateGradientScore(double[] grad) { // FuzzyThreshold sigmaMagnitudeLow = new FuzzyThreshold(3, 7); // FuzzyThreshold sigmaDirection = new FuzzyThreshold(-60, -35); // double magn = GradientCalculator.calculateGradMagn(grad); // double dir = GradientCalculator.calculateGradDir(grad); // if (dir > 90) dir -= 180; // if (dir > 0) dir *= -1; // double magnScoreLow = sigmaMagnitudeLow.f(magn); // double dirScore = sigmaDirection.f(dir); // if (magn > 80) // return 0; // if (magnScoreLow < dirScore) // return magnScoreLow; // return dirScore; // } // private void buildGradientImg() { // BufferedImage gradientImg = new BufferedImage(original.width / 2 - 1, original.height - 1, BufferedImage.TYPE_BYTE_GRAY); // WritableRaster raster = gradientImg.getRaster(); // for (int i = 1; i < original.height - 1; i++) { // for (int j = 1; j < (original.width / 2 - 1); j += 1) { // int[] pixel = new int[1]; // double[] grad = GradientCalculator.calculateGrad(original.yPixelsCenteredAt(j, i)); // pixel[0] = (int)(255*calculateGradientScore(grad)); // raster.setPixel(j-1, i-1, pixel); // } // } // gradient = gradientImg; // } // // private double calculateFieldScore(int yMode, int y) { // // int diff = y - yMode; // // if (diff < 0) // // return 0.0; // // FuzzyThreshold sigma = new FuzzyThreshold(40, 60); // // return sigma.f(diff); // // } // // // // private int calculateYMode() { // // int[] frequencies = new int[256]; // // for (int i = original.height / 2; i < original.height; i++) { // // for (int j = 0; j < (original.width / 2); j += 1) { // // frequencies[original.yPixelAt(j, i)] += 1; // // } // // } // // // // int mode = 0, frequencyOfMode = 0; // // for (int i = 0; i < 256; i++) { // // if (frequencies[i] > frequencyOfMode) { // // mode = i; // // frequencyOfMode = frequencies[i]; // // } // // } // // return mode; // // } // // // // private void buildFieldImg() { // // BufferedImage fieldImg = new BufferedImage(original.width / 2 - 1, original.height - 1, BufferedImage.TYPE_BYTE_GRAY); // // int yMode = calculateYMode(); // // WritableRaster raster = fieldImg.getRaster(); // // for (int i = 1; i < original.height - 1; i++) { // // for (int j = 1; j < (original.width / 2 - 1); j += 1) { // // int[] pixel = new int[1]; // // int y = original.yPixelAt(j, i); // // pixel[0] = (int)(255*calculateFieldScore(yMode, y)); // // raster.setPixel(j-1, i-1, pixel); // // } // // } // // field = fieldImg; // // } // private void buildHistogram() { // Raster raster = post.getData(); // int width = post.getWidth(); // int height = post.getHeight(); // double[] hist = new double[width]; // for (int x = 25; x < width - 25; x++) { // // boolean inRun = false; // // double score = 0; // for (int y = 0; y < height; y++) { // int[] pixel = new int[1]; // raster.getPixel(x, y, pixel); // hist[x] += pixel[0]; // // if (pixel[0] > 0) { // // if (!inRun) { // // inRun = true; // // score += (double) pixel[0]; // // } else { // // score += (double) pixel[0]; // // } // // } else if (inRun) { // // inRun = false; // // if (score > hist[x]) // // hist[x] = score; // // score = 0; // // } // } // } // double maxScore = 0; // for (int i = 25; i < width - 25; i++) { // if (hist[i] > maxScore) // maxScore = hist[i]; // } // for (int i = 25; i < width - 25; i++) { // hist[i] = hist[i] / maxScore * 255; // } // rawScores = hist; // } // private void processHistogram() { // double narrowGaussian[] = new double[] {0.000003, 0.000229, 0.005977, 0.060598, 0.24173, 0.382925, 0.24173, 0.060598, 0.005977, 0.000229, 0.000003}; // double wideGaussian[] = new double[] {0.01554, 0.015969, 0.016392, 0.016807, 0.017213, 0.017609, 0.017995, 0.018369, 0.018729, 0.019076, 0.019407, // 0.019722, 0.020021, 0.0203, 0.020562, 0.020803, 0.021024, 0.021223, 0.021401, 0.021556, 0.021688, 0.021796, // 0.021881, 0.021942, 0.021979, 0.021991, 0.021979, 0.021942, 0.021881, 0.021796, 0.021688, 0.021556, 0.021401, // 0.021223, 0.021024, 0.020803, 0.020562, 0.0203, 0.020021, 0.019722, 0.019407, 0.019076, 0.018729, 0.018369, // 0.017995, 0.017609, 0.017213, 0.016807, 0.016392, 0.015969, 0.01554}; // processedScores = new double[rawScores.length]; // for (int i = 25; i < processedScores.length - 25; i++) { // processedScores[i] = convolve(rawScores, narrowGaussian, i) - convolve(rawScores, wideGaussian, i); // } // } // private void detectPeaks() { // candidates = new ArrayList<Integer>(); // int threshold = 40; // int leftLimit = 0; // boolean inPeak = false; // for (int i = 0; i < processedScores.length; i++) { // if (processedScores[i] >= threshold & !inPeak) { // leftLimit = i; // inPeak = true; // } else if (processedScores[i] < threshold && inPeak) { // candidates.add((leftLimit + i) / 2); // inPeak = false; // } // } // } // // TODO rename // private double convolve(double[] array, double[] kernel, int index) { // double sum = 0; // for (int i = 0; i < kernel.length; i++) { // int j = index - kernel.length / 2 + i; // if (j >= 0 && j < array.length) // sum += array[j]*kernel[i]; // } // return sum; // } // }