All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boofcv.abst.feature.detect.line.DetectLineHoughPolar Maven / Gradle / Ivy

Go to download

BoofCV is an open source Java library for real-time computer vision and robotics applications.

There is a newer version: 0.26
Show newest version
/*
 * Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved.
 *
 * This file is part of BoofCV (http://boofcv.org).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package boofcv.abst.feature.detect.line;


import boofcv.abst.feature.detect.extract.ConfigExtract;
import boofcv.abst.feature.detect.extract.NonMaxSuppression;
import boofcv.abst.filter.derivative.ImageGradient;
import boofcv.alg.feature.detect.edge.GGradientToEdgeFeatures;
import boofcv.alg.feature.detect.line.HoughTransformLinePolar;
import boofcv.alg.feature.detect.line.ImageLinePruneMerge;
import boofcv.alg.filter.binary.ThresholdImageOps;
import boofcv.factory.feature.detect.extract.FactoryFeatureExtractor;
import boofcv.struct.image.ImageFloat32;
import boofcv.struct.image.ImageSingleBand;
import boofcv.struct.image.ImageUInt8;
import georegression.struct.line.LineParametric2D_F32;
import org.ddogleg.struct.FastQueue;

import java.util.ArrayList;
import java.util.List;

/**
 * 

* Full processing chain for detecting lines using a Hough transform with polar parametrization. *

* *

* USAGE NOTES: Blurring the image prior to processing can often improve performance. * Results will not be perfect and to detect all the obvious lines in the image several false * positives might be returned. *

* * @see boofcv.alg.feature.detect.line.HoughTransformLinePolar * * @author Peter Abeles */ public class DetectLineHoughPolar implements DetectLine { // transform algorithm HoughTransformLinePolar alg; // extractor used by hough transform NonMaxSuppression extractor; // computes image gradient ImageGradient gradient; // used to create binary edge image float thresholdEdge; // image gradient D derivX; D derivY; // edge intensity image ImageFloat32 intensity = new ImageFloat32(1,1); // detected edge image ImageUInt8 binary = new ImageUInt8(1,1); ImageFloat32 suppressed = new ImageFloat32(1,1); // ImageFloat32 angle = new ImageFloat32(1,1); // ImageSInt8 direction = new ImageSInt8(1,1); // angle tolerance for post processing pruning float pruneAngleTol; // range tolerance for post processing pruning float pruneRangeTol; // size of range bin in pixels double resolutionRange; // size of angle bin in radians double resolutionAngle; // radius for local max int localMaxRadius; // the maximum number of lines it will return int maxLines; // post processing pruning ImageLinePruneMerge post = new ImageLinePruneMerge(); /** * Configures hough line detector. * * @param localMaxRadius Radius for local maximum suppression. Try 2. * @param minCounts Minimum number of counts for detected line. Critical tuning parameter and image dependent. * @param resolutionRange Resolution of line range in pixels. Try 2 * @param resolutionAngle Resolution of line angle in radius. Try PI/180 * @param thresholdEdge Edge detection threshold. Try 50. * @param maxLines Maximum number of lines to return. If ≤ 0 it will return them all. * @param gradient Algorithm for computing image gradient. */ public DetectLineHoughPolar(int localMaxRadius, int minCounts, double resolutionRange , double resolutionAngle , float thresholdEdge, int maxLines , ImageGradient gradient) { pruneAngleTol = (float)((localMaxRadius+1)*resolutionAngle); pruneRangeTol = (float)((localMaxRadius+1)*resolutionRange); this.localMaxRadius = localMaxRadius; this.gradient = gradient; this.thresholdEdge = thresholdEdge; this.resolutionRange = resolutionRange; this.resolutionAngle = resolutionAngle; this.maxLines = maxLines <= 0 ? Integer.MAX_VALUE : maxLines; extractor = FactoryFeatureExtractor.nonmax(new ConfigExtract(localMaxRadius, minCounts, 0, false)); derivX = gradient.getDerivativeType().createImage(1, 1); derivY = gradient.getDerivativeType().createImage(1, 1); } @Override public List detect(I input) { // see if the input image shape has changed. if( derivX.width != input.width || derivY.height != input.height ) { double r = Math.sqrt(input.width*input.width + input.height*input.height); int numBinsRange = (int)Math.ceil(r/resolutionRange); int numBinsAngle = (int)Math.ceil(Math.PI/resolutionAngle); alg = new HoughTransformLinePolar(extractor,numBinsRange,numBinsAngle); derivX.reshape(input.width,input.height); derivY.reshape(input.width,input.height); intensity.reshape(input.width,input.height); binary.reshape(input.width, input.height); // angle.reshape(input.width, input.height); // direction.reshape(input.width, input.height); suppressed.reshape(input.width, input.height); } gradient.process(input, derivX, derivY); GGradientToEdgeFeatures.intensityAbs(derivX, derivY, intensity); // non-max suppression reduces the number of line pixels, reducing the number of false positives // When too many pixels are flagged, then more curves randomly cross over in transform space causing // false positives // GGradientToEdgeFeatures.direction(derivX, derivY, angle); // GradientToEdgeFeatures.discretizeDirection4(angle, direction); // GradientToEdgeFeatures.nonMaxSuppression4(intensity,direction, suppressed); GGradientToEdgeFeatures.nonMaxSuppressionCrude4(intensity,derivX,derivY,suppressed); ThresholdImageOps.threshold(suppressed, binary, thresholdEdge, false); alg.transform(binary); FastQueue lines = alg.extractLines(); List ret = new ArrayList(); for( int i = 0; i < lines.size; i++ ) ret.add(lines.get(i)); ret = pruneLines(input, ret); return ret; } private List pruneLines(I input, List ret) { float intensity[] = alg.getFoundIntensity(); post.reset(); for( int i = 0; i < ret.size(); i++ ) { post.add(ret.get(i),intensity[i]); } post.pruneSimilar(pruneAngleTol, pruneRangeTol, input.width, input.height); post.pruneNBest(maxLines); return post.createList(); } public HoughTransformLinePolar getTransform() { return alg; } public D getDerivX() { return derivX; } public D getDerivY() { return derivY; } public ImageFloat32 getEdgeIntensity() { return intensity; } public ImageUInt8 getBinary() { return binary; } }