public void process(BufferedImage input) { setInputImage(input); image.reshape(input.getWidth(), input.getHeight()); transform.reshape(input.getWidth(), input.getHeight()); magnitude.reshape(input.getWidth(), input.getHeight()); phase.reshape(input.getWidth(), input.getHeight()); ConvertBufferedImage.convertFrom(input, image, true); fft.forward(image, transform); GDiscreteFourierTransformOps.shiftZeroFrequency(transform, true); GDiscreteFourierTransformOps.magnitude(transform, magnitude); GDiscreteFourierTransformOps.phase(transform, phase); // Convert it to a log scale for visibility GPixelMath.log(magnitude, magnitude); SwingUtilities.invokeLater( new Runnable() { public void run() { setPreferredSize(new Dimension(image.width + 50, image.height + 20)); processedImage = true; } }); doRefreshAll(); }
public Segmenter(ImageUInt8 gray) { // Downsample image to smaller size int sampleWidth = 300; this.scale = (1.0 * gray.getWidth()) / sampleWidth; int sampleHeight = (int) (gray.getHeight() / scale); ImageUInt8 sample = new ImageUInt8(sampleWidth, sampleHeight); boofcv.alg.distort.DistortImageOps.scale( gray, sample, boofcv.alg.interpolate.TypeInterpolate.NEAREST_NEIGHBOR); this.sample = sample; // Calculate mean this.mean = GPixelMath.sum(gray) / (gray.width * gray.height); this.threshold = this.calculateThreshold(); Log.i( "Setalyzer", "brightness histogram: " + Arrays.toString(this.brightnessHistogram.histogram)); // Blur image and store blurred image this.blurred = boofcv.alg.filter.blur.BlurImageOps.mean(sample, null, BLUR_RADIUS, null); // Create binary image and label blobs for threshold-based segmentation // Log.i("Setalyzer", "THreshold value is " + this.mean); // Threshold to generate binary image ImageUInt8 binary = boofcv.alg.filter.binary.ThresholdImageOps.threshold( this.blurred, null, (int) this.mean, false); ImageSInt32 blobImage = FactoryImage.create(ImageSInt32.class, sample.getWidth(), sample.getHeight()); this.numBlobs = boofcv.alg.filter.binary.BinaryImageOps.labelBlobs4(binary, blobImage); this.blobQuads = quadsFromBlobs(blobImage, numBlobs); // Canny detect edges and store them // Dynamic canny edge, which sets the threshold as a function of the image's edge intensity DetectEdgeContour<ImageUInt8> cannyD = FactoryDetectEdgeContour.canny(0.05, 0.15, true, ImageUInt8.class, ImageSInt16.class); cannyD.process(blurred); List<List<Point2D_I32>> edges = cannyD.getContours(); // Prune edges which are obviously not cards List<List<Point2D_F64>> prunedEdgeList = new ArrayList<List<Point2D_F64>>(); for (List<Point2D_I32> edge : edges) { // Disregard tiny contours if (edge.size() < EDGE_SIZE_THRESHOLD) { continue; } // Disregard shapes with blatantly non-card shapes // if (!isCardShaped(edge)) { // continue; // } List<Point2D_F64> f64Edge = new ArrayList<Point2D_F64>(); for (Point2D_I32 p : edge) { f64Edge.add(new Point2D_F64(p.x, p.y)); } prunedEdgeList.add(f64Edge); } this.prunedCannyEdgeList = prunedEdgeList; }