/** * Converts the gray scale image into a binary number. Skip the outer 1 pixel of each inner square. These * tend to be incorrectly classified due to distortion. */ protected void findBitCounts(GrayF32 gray , double threshold ) { // compute binary image using an adaptive algorithm to handle shadows ThresholdImageOps.threshold(gray,binaryInner,(float)threshold,true); Arrays.fill(counts, 0); for (int row = 0; row < gridWidth; row++) { int y0 = row * binaryInner.width / gridWidth + 1; int y1 = (row + 1) * binaryInner.width / gridWidth - 1; for (int col = 0; col < gridWidth; col++) { int x0 = col * binaryInner.width / gridWidth + 1; int x1 = (col + 1) * binaryInner.width / gridWidth - 1; int total = 0; for (int i = y0; i < y1; i++) { int index = i * binaryInner.width + x0; for (int j = x0; j < x1; j++) { total += binaryInner.data[index++]; } } counts[row * gridWidth + col] = total; } } }
return ThresholdImageOps.localGaussian((GrayF32) input, output, width, (float) scale, down, (GrayF32) work1, (GrayF32) work2); } else if( input instanceof GrayU8) { return ThresholdImageOps.localGaussian((GrayU8) input, output, width, (float) scale, down, (GrayU8) work1, (GrayU8) work2); } else {
return ThresholdImageOps.threshold((GrayF32)input,output,(float)threshold,down); } else if( input instanceof GrayU8) { return ThresholdImageOps.threshold((GrayU8)input,output,(int)threshold,down); } else if( input instanceof GrayU16) { return ThresholdImageOps.threshold((GrayU16)input,output,(int)threshold,down); } else if( input instanceof GrayS16) { return ThresholdImageOps.threshold((GrayS16)input,output,(int)threshold,down); } else if( input instanceof GrayS32) { return ThresholdImageOps.threshold((GrayS32)input,output,(int)threshold,down); } else if( input instanceof GrayF64) { return ThresholdImageOps.threshold((GrayF64)input,output,threshold,down); } else { throw new IllegalArgumentException("Unknown image type: "+input.getClass().getSimpleName());
ThresholdImageOps.threshold(input, binary, (float) mean, true);
@Override public List<LineParametric2D_F32> detect(I input) { derivX.reshape(input.width,input.height); derivY.reshape(input.width,input.height); intensity.reshape(input.width,input.height); binary.reshape(input.width,input.height); gradient.process(input,derivX,derivY); GGradientToEdgeFeatures.intensityAbs(derivX, derivY, intensity); ThresholdImageOps.threshold(intensity, binary, thresholdEdge, false); alg.transform(derivX,derivY,binary); FastQueue<LineParametric2D_F32> lines = alg.extractLines(); List<LineParametric2D_F32> ret = new ArrayList<>(); for( int i = 0; i < lines.size; i++ ) ret.add(lines.get(i)); ret = pruneLines(input,ret); return ret; }
ThresholdImageOps.threshold(suppressed, binary, thresholdEdge, false);
@Override public List<LineParametric2D_F32> detect(I input) { derivX.reshape(input.width,input.height); derivY.reshape(input.width,input.height); intensity.reshape(input.width,input.height); binary.reshape(input.width,input.height); gradient.process(input,derivX,derivY); GGradientToEdgeFeatures.intensityAbs(derivX, derivY, intensity); ThresholdImageOps.threshold(intensity, binary, thresholdEdge, false); List<LineParametric2D_F32> ret = new ArrayList<>(); post.reset(); for( int i = 0; i < totalVerticalDivisions; i++ ) { int y0 = input.height*i/totalVerticalDivisions; int y1 = input.height*(i+1)/totalVerticalDivisions; for( int j = 0; j < totalHorizontalDivisions; j++ ) { int x0 = input.width*j/totalVerticalDivisions; int x1 = input.width*(j+1)/totalVerticalDivisions; processSubimage(x0,y0,x1,y1,ret); } } // removing duplicate lines caused by processing sub-images ret = pruneLines(input); return ret; }
public BufferedImage findRoad(BufferedImage src) { // convert into a usable format ImageFloat32 input = ConvertBufferedImage.convertFromSingle(src, null, ImageFloat32.class); ImageUInt8 binary = new ImageUInt8(input.width, input.height); ImageSInt32 blobs = new ImageSInt32(input.width, input.height); // the mean pixel value is often a reasonable threshold when creating a binary image double mean = ImageStatistics.mean(input); // create a binary image ThresholdImageOps.threshold(input, binary, (float) mean, true); // remove small blobs through erosion and dilation // The null in the input indicates that it should internally declare the work image it needs // this is less efficient, but easier to code. for (int i = 0; i < 1; i++) { binary = BinaryImageOps.erode8(binary,1, null); } for (int i = 0; i < 2; i++) { binary = BinaryImageOps.dilate8(binary,1, null); } // Detect blobs inside the binary image and assign labels to them List<Contour> blobContours = BinaryImageOps.contour(binary, ConnectRule.FOUR, blobs); int numBlobs = filterBlobsNotTouchingEdges(blobs, blobContours.size()); // Render the binary image for output and display it in a window BufferedImage dst = VisualizeBinaryData.renderLabeled(blobs, numBlobs, null); return dst; }
@Override public void process(GrayU8 input) { // Select a reasonable threshold double mean = GThresholdImageOps.computeOtsu(input,0,255); // create a binary image by thresholding ThresholdImageOps.threshold(input, binary, (int)mean, down); // reduce noise with some filtering BinaryImageOps.removePointNoise(binary, filtered1); // draw binary image for output if( showBinary ) { VisualizeImageData.binaryToBitmap(filtered1, false, bitmap, bitmapTmp); } else { ConvertBitmap.boofToBitmap(input,bitmap,bitmapTmp); } // draw the ellipses findContours.process(filtered1,contourOutput); List<Contour> contours = BinaryImageOps.contour(filtered1, ConnectRule.EIGHT,null); resetShapes(); for (Contour contour : contours) { List<Point2D_I32> points = contour.external; if (points.size() < 20) continue; fitShape(points); } finalizeShapes(); visualizationPending = true; } }