public void process(BufferedImage image) { setInputImage(image); T gray = ConvertBufferedImage.convertFromSingle(image, null, imageType); ss.setImage(gray); gui.reset(); for (int i = 0; i < ss.getTotalScales(); i++) { ss.setActiveScale(i); double scale = ss.getCurrentScale(); T scaledImage = ss.getScaledImage(); BufferedImage b = ConvertBufferedImage.convertTo(scaledImage, null); gui.addImage(b, String.format("Scale %6.2f", scale)); } processedImage = true; }
private synchronized void setLevel(int level) { // System.out.println("level "+level); if (level > 0) { ImageSingleBand small = ss.getLayer(level - 1); ImageSingleBand enlarge = GeneralizedImageOps.createSingleBand( small.getClass(), ss.getInputWidth(), ss.getInputHeight()); DistortImageOps.scale(small, enlarge, TypeInterpolate.NEAREST_NEIGHBOR); // if the size isn't the same null it so a new image will be declared if (levelImage != null && (levelImage.getWidth() != enlarge.width || levelImage.getHeight() != enlarge.height)) { levelImage = null; } levelImage = ConvertBufferedImage.convertTo(enlarge, levelImage); double scale = ss.getScale(level - 1); levelPoints.clear(); for (ScalePoint p : points) { if (p.scale == scale) { levelPoints.add(p); } } } else { levelPoints.clear(); levelPoints.addAll(points); } this.activeLevel = level; }
/** * **************************************************************************************************************************************** */ private static List<List<PointIndex_I32>> getCandidates( BufferedImage image, int blurRadius, float threshLow, float threshHigh, double toleranceDist, double toleranceAngle, boolean dynamicThreshold) { List<List<PointIndex_I32>> candidates = new ArrayList<List<PointIndex_I32>>(); ImageFloat32 input = ConvertBufferedImage.convertFromSingle(image, null, ImageFloat32.class); ImageUInt8 binary = new ImageUInt8(input.width, input.height); // Finds edges inside the image CannyEdge<ImageFloat32, ImageFloat32> canny = FactoryEdgeDetectors.canny( blurRadius, false, dynamicThreshold, ImageFloat32.class, ImageFloat32.class); canny.process(input, threshLow, threshHigh, binary); List<Contour> contours = BinaryImageOps.contour(binary, rule, null); for (Contour c : contours) { // Only the external contours are relevant. List<PointIndex_I32> vertices = ShapeFittingOps.fitPolygon(c.external, true, toleranceDist, toleranceAngle, 100); candidates.add(vertices); } return candidates; }
/** * Detects lines inside the image using different types of Hough detectors * * @param image Input image. * @param imageType Type of image processed by line detector. * @param derivType Type of image derivative. */ public static <T extends ImageSingleBand, D extends ImageSingleBand> void detectLines( BufferedImage image, Class<T> imageType, Class<D> derivType) { // convert the line into a single band image T input = ConvertBufferedImage.convertFromSingle(image, null, imageType); // Comment/uncomment to try a different type of line detector DetectLineHoughPolar<T, D> detector = FactoryDetectLineAlgs.houghPolar( new ConfigHoughPolar(3, 30, 2, Math.PI / 180, edgeThreshold, maxLines), imageType, derivType); // DetectLineHoughFoot<T,D> detector = FactoryDetectLineAlgs.houghFoot( // new ConfigHoughFoot(3, 8, 5, edgeThreshold,maxLines), imageType, derivType); // DetectLineHoughFootSubimage<T,D> detector = FactoryDetectLineAlgs.houghFootSub( // new ConfigHoughFootSubimage(3, 8, 5, edgeThreshold,maxLines, 2, 2), imageType, derivType); List<LineParametric2D_F32> found = detector.detect(input); // display the results ImageLinePanel gui = new ImageLinePanel(); gui.setBackground(image); gui.setLines(found); gui.setPreferredSize(new Dimension(image.getWidth(), image.getHeight())); listPanel.addItem(gui, "Found Lines"); }
public static BufferedImage standard(ImageSingleBand<?> src, BufferedImage dst) { if (src.getDataType().isInteger()) { ImageInteger srcInt = (ImageInteger) src; if (src.getDataType().isSigned()) { double max = GImageStatistics.maxAbs(srcInt); return colorizeSign(srcInt, dst, (int) max); } else { if (src.getDataType().getNumBits() == 8) { dst = ConvertBufferedImage.convertTo((ImageUInt8) src, dst); } else { double max = GImageStatistics.maxAbs(srcInt); dst = grayUnsigned(srcInt, dst, (int) max); } } } else if (ImageFloat32.class.isAssignableFrom(src.getClass())) { ImageFloat32 img = (ImageFloat32) src; float max = ImageStatistics.maxAbs(img); boolean hasNegative = false; for (int i = 0; i < img.getHeight(); i++) { for (int j = 0; j < img.getWidth(); j++) { if (img.get(j, i) < 0) { hasNegative = true; break; } } } if (hasNegative) return colorizeSign(img, dst, (int) max); else return grayMagnitude((ImageFloat32) src, dst, max); } return dst; }
public void process(final BufferedImage buffLeft, final BufferedImage buffRight) { imageLeft.reshape(buffLeft.getWidth(), buffLeft.getHeight()); imageRight.reshape(buffRight.getWidth(), buffRight.getHeight()); grayLeft.reshape(buffLeft.getWidth(), buffLeft.getHeight()); grayRight.reshape(buffRight.getWidth(), buffRight.getHeight()); ConvertBufferedImage.convertFromMulti(buffLeft, imageLeft, true, imageType); ConvertBufferedImage.convertFromMulti(buffRight, imageRight, true, imageType); SwingUtilities.invokeLater( new Runnable() { public void run() { panel.setImages(buffLeft, buffRight); processedImage = true; doRefreshAll(); } }); }
public static void main(String args[]) { // load and convert the image into a usable format BufferedImage image = UtilImageIO.loadImage("../data/applet/shapes02.png"); ImageFloat32 input = ConvertBufferedImage.convertFromSingle(image, null, ImageFloat32.class); ShowImages.showWindow(image, "Original"); fitCannyEdges(input); fitCannyBinary(input); fitBinaryImage(input); }
public void process(final BufferedImage input) { setInputImage(input); this.input = input; workImage = ConvertBufferedImage.convertFromSingle(input, null, imageType); scaledIntensity = new ImageFloat32(workImage.width, workImage.height); pyramid.setImage(workImage); SwingUtilities.invokeLater( new Runnable() { public void run() { setPreferredSize(new Dimension(input.getWidth(), input.getHeight())); processedImage = true; } }); doRefreshAll(); }
public static void main(String args[]) { BufferedImage input = UtilImageIO.loadImage("../data/evaluation/sunflowers.png"); // BufferedImage input = UtilImageIO.loadImage("../data/evaluation/shapes01.png"); ImageFloat32 gray = ConvertBufferedImage.convertFromSingle(input, null, ImageFloat32.class); SiftDetector alg = FactoryInterestPointAlgs.siftDetector(new ConfigSiftDetector(3, 10, 150, 5)); SiftImageScaleSpace imageSS = new SiftImageScaleSpace(1.6f, 5, 4, false); imageSS.constructPyramid(gray); imageSS.computeFeatureIntensity(); alg.process(imageSS); System.out.println("total features found: " + alg.getFoundPoints().size()); VisualizeFeatures.drawScalePoints( input.createGraphics(), alg.getFoundPoints().toList(), BoofDefaults.SCALE_SPACE_CANONICAL_RADIUS); ListDisplayPanel dog = new ListDisplayPanel(); for (int i = 0; i < alg.ss.dog.length; i++) { int scale = i % (alg.ss.numScales - 1); int octave = i / (alg.ss.numScales - 1); BufferedImage img = VisualizeImageData.colorizeSign(alg.ss.dog[i], null, -1); dog.addImage(img, octave + " " + scale); } ListDisplayPanel ss = new ListDisplayPanel(); for (int i = 0; i < alg.ss.scale.length; i++) { int scale = i % alg.ss.numScales; int octave = i / alg.ss.numScales; BufferedImage img = VisualizeImageData.grayMagnitude(alg.ss.scale[i], null, 255); ss.addImage(img, octave + " " + scale); } ShowImages.showWindow(dog, "Octave DOG"); ShowImages.showWindow(ss, "Octave Scales"); ShowImages.showWindow(input, "Found Features"); System.out.println("Done"); }
/** * Detects segments inside the image * * @param image Input image. * @param imageType Type of image processed by line detector. * @param derivType Type of image derivative. */ public static <T extends ImageSingleBand, D extends ImageSingleBand> void detectLineSegments( BufferedImage image, Class<T> imageType, Class<D> derivType) { // convert the line into a single band image T input = ConvertBufferedImage.convertFromSingle(image, null, imageType); // Comment/uncomment to try a different type of line detector DetectLineSegmentsGridRansac<T, D> detector = FactoryDetectLineAlgs.lineRansac(40, 30, 2.36, true, imageType, derivType); List<LineSegment2D_F32> found = detector.detect(input); // display the results ImageLinePanel gui = new ImageLinePanel(); gui.setBackground(image); gui.setLineSegments(found); gui.setPreferredSize(new Dimension(image.getWidth(), image.getHeight())); listPanel.addItem(gui, "Found Line Segments"); }
/** * Renders a colored image where the color indicates the sign and intensity its magnitude. The * input is divided by normalize to render it in the appropriate scale. * * @param src Input single band image. * @param dst Where the image is rendered into. If null a new BufferedImage will be created and * return. * @param normalize Used to normalize the input image. If <= 0 then the max value will be used * @return Rendered image. */ public static BufferedImage colorizeSign( ImageSingleBand src, BufferedImage dst, double normalize) { dst = checkInputs(src, dst); if (normalize <= 0) { normalize = GImageStatistics.maxAbs(src); } if (normalize == 0) { // sets the output to black ConvertBufferedImage.convertTo(src, dst, true); return dst; } if (src.getClass().isAssignableFrom(ImageFloat32.class)) { return colorizeSign((ImageFloat32) src, dst, (float) normalize); } else { return colorizeSign((ImageInteger) src, dst, (int) normalize); } }
public static void main(String[] args) throws IOException { if (args.length == 0) { System.out.println( "usage: crop-objects [OPTION]... FILE [DIR]\n" + "crops detected objects from image FILE and writes their subimages to files. \n" + "Can specify the DIR in which to create the files, otherwise subimage files are " + "created in the same directory as FILE is in by default. \n" + "-t [n] [m] set the high and low threshold values. n and m are values between 0 and 1."); System.exit(1); } // interpret options and read arguments if (args[0].equals("-t")) { threshLow = Float.parseFloat(args[1]); threshHigh = Float.parseFloat(args[2]); filename = args[3]; if (args.length == 5) { dir = args[4]; } } else { filename = args[0]; if (args.length == 2) { dir = args[1]; } } // get path to directory file is in String name = FilenameUtils.removeExtension(filename); // get image BufferedImage image = UtilImageIO.loadImage(new File(filename).getAbsolutePath()); if (image == null) { System.out.println( "usage: crop-objects [OPTION]... FILE [DIR]\n" + "crops detected objects from image FILE and writes their subimages to files. \n" + "Can specify the DIR in which to create the files, otherwise subimage files are " + "created in the same directory as FILE is in by default. \n" + "-t [n] [m] set the high and low threshold values. n and m are values between 0 and 1."); System.exit(1); } minsize = (int) (0.1 * Math.min(image.getHeight(), image.getWidth())); // find objects in image // generate candidate contours ArrayList<List<PointIndex_I32>> objects = new ArrayList<List<PointIndex_I32>>(); List<BufferedImage> results = new ArrayList<BufferedImage>(); List<List<PointIndex_I32>> candidates = new ArrayList<List<PointIndex_I32>>(); ImageFloat32 input = ConvertBufferedImage.convertFromSingle(image, null, ImageFloat32.class); BufferedImage bw = ConvertBufferedImage.convertTo( input, new BufferedImage(image.getWidth(), image.getHeight(), image.getType())); File binaryfile = new File(name + "_" + "binary.png"); ImageIO.write(bw, "png", binaryfile); ImageUInt8 binary = new ImageUInt8(input.width, input.height); // Finds edges inside the image CannyEdge<ImageFloat32, ImageFloat32> canny = FactoryEdgeDetectors.canny( blurRadius, true, dynamicThreshold, ImageFloat32.class, ImageFloat32.class); canny.process(input, threshLow, threshHigh, binary); List<Contour> contours = BinaryImageOps.contour(binary, rule, null); BufferedImage visualBinary = VisualizeBinaryData.renderBinary(binary, null); File cannyfile = new File(name + "_" + "canny.png"); ImageIO.write(visualBinary, "png", cannyfile); BufferedImage cannyContour = VisualizeBinaryData.renderExternal(contours, null, binary.width, binary.height, null); File cannyContourfile = new File(name + "_" + "contour.png"); ImageIO.write(cannyContour, "png", cannyContourfile); for (Contour c : contours) { // Only the external contours are relevant. List<PointIndex_I32> vertices = ShapeFittingOps.fitPolygon(c.external, true, toleranceDist, toleranceAngle, 100); candidates.add(vertices); } for (List<PointIndex_I32> vertices : candidates) { try { Candidate c = new Candidate(vertices, image); if (c.size(minsize)) { c.rotate(); results.add(c.getImage()); objects.add(vertices); } } catch (Exception e) { System.out.println("Error creating candidate from contour " + e.getMessage()); } } // write subimages of objects to files int i = 0; for (BufferedImage obj : results) { // print images to file try { File outputfile = new File(name + "_" + i + ".png"); i++; ImageIO.write(obj, "png", outputfile); } catch (IOException e) { System.out.println("Error writing subimages" + e.getMessage()); } } // draw objects onto original image and save Draw.drawPolygons(objects, image); File outputfile = new File(name + "_" + "annotated.png"); ImageIO.write(image, "png", outputfile); }
public <II extends ImageSingleBand> double[][] harder(BufferedImage image) { MultiSpectral<ImageFloat32> colorImage = ConvertBufferedImage.convertFromMulti(image, null, true, ImageFloat32.class); // convert the color image to greyscale ImageFloat32 greyscaleImage = ConvertImage.average((MultiSpectral<ImageFloat32>) colorImage, null); // SURF works off of integral images Class<II> integralType = GIntegralImageOps.getIntegralType(ImageFloat32.class); // define the feature detection algorithm NonMaxSuppression extractor = FactoryFeatureExtractor.nonmax(new ConfigExtract(2, detectThreshold, 5, true)); FastHessianFeatureDetector<II> detector = new FastHessianFeatureDetector<II>(extractor, maxFeaturesPerScale, 2, 9, 4, 4); // estimate orientation OrientationIntegral<II> orientation = FactoryOrientationAlgs.sliding_ii(null, integralType); DescribePointSurf<II> descriptor = FactoryDescribePointAlgs.<II>surfStability(null, integralType); // compute the integral image of the greyscale 'image' II integralgrey = GeneralizedImageOps.createSingleBand( integralType, greyscaleImage.width, greyscaleImage.height); GIntegralImageOps.transform(greyscaleImage, integralgrey); // detect fast hessian features detector.detect(integralgrey); // === This is the point were the code starts deviating from the standard SURF! === // tell algorithms which image to process orientation.setImage(integralgrey); List<ScalePoint> points = detector.getFoundPoints(); double[][] descriptions = new double[points.size()][3 * descriptor.getDescriptionLength()]; double[] angles = new double[points.size()]; int l = 0; for (ScalePoint p : points) { orientation.setScale(p.scale); angles[l] = orientation.compute(p.x, p.y); l++; } for (int i = 0; i < 3; i++) { // check if it is actually a greyscale image, take always the 1st band! ImageFloat32 colorImageBand = null; if (colorImage.getNumBands() == 1) { colorImageBand = colorImage.getBand(0); } else { colorImageBand = colorImage.getBand(i); } // compute the integral image of the i-th band of the color 'image' II integralband = GeneralizedImageOps.createSingleBand( integralType, colorImageBand.width, colorImageBand.height); GIntegralImageOps.transform(colorImageBand, integralband); // tell algorithms which image to process // orientation.setImage(integralband); descriptor.setImage(integralband); int j = 0; for (ScalePoint p : points) { // estimate orientation // orientation.setScale(p.scale); // double angle = orientation.compute(p.x, p.y); // extract the SURF description for this region SurfFeature desc = descriptor.createDescription(); descriptor.describe(p.x, p.y, angles[j], p.scale, (TupleDesc_F64) desc); double[] banddesc = desc.getValue(); if (perBandNormalization) { banddesc = Normalization.normalizeL2(banddesc); } for (int k = 0; k < SURFLength; k++) { descriptions[j][i * SURFLength + k] = banddesc[k]; } j++; } } return descriptions; }