boofcv.abst.feature.detect.line.DetectLineHoughFoot Maven / Gradle / Ivy
/*
* Copyright (c) 2011-2017, 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.HoughTransformLineFootOfNorm;
import boofcv.alg.feature.detect.line.ImageLinePruneMerge;
import boofcv.alg.filter.binary.ThresholdImageOps;
import boofcv.factory.feature.detect.extract.FactoryFeatureExtractor;
import boofcv.struct.image.GrayF32;
import boofcv.struct.image.GrayU8;
import boofcv.struct.image.ImageGray;
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 foot of norm parametrization inside
* a Hough transform.
*
*
*
* 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.HoughTransformLineFootOfNorm
*
* @author Peter Abeles
*/
public class DetectLineHoughFoot , D extends ImageGray> implements DetectLine {
// transform algorithm
HoughTransformLineFootOfNorm alg;
// computes image gradient
ImageGradient gradient;
// used to create binary edge image
float thresholdEdge;
// image gradient
D derivX;
D derivY;
// edge intensity image
GrayF32 intensity = new GrayF32(1,1);
// detected edge image
GrayU8 binary = new GrayU8(1,1);
// the maximum number of lines it will return
int maxLines;
// post processing pruning
ImageLinePruneMerge post = new ImageLinePruneMerge();
/**
* Specifies detection parameters. The suggested parameters should be used as a starting point and will
* likely need to be tuned significantly for each different scene.
*
* @param localMaxRadius Lines in transform space must be a local max in a region with this radius. Try 5;
* @param minCounts Minimum number of counts/votes inside the transformed image. Try 5.
* @param minDistanceFromOrigin Lines which are this close to the origin of the transformed image are ignored. Try 5.
* @param thresholdEdge Threshold for classifying pixels as edge or not. Try 30.
* @param gradient Computes the image gradient.
*/
public DetectLineHoughFoot( int localMaxRadius,
int minCounts ,
int minDistanceFromOrigin ,
float thresholdEdge ,
int maxLines ,
ImageGradient gradient )
{
this.gradient = gradient;
this.thresholdEdge = thresholdEdge;
this.maxLines = maxLines;
NonMaxSuppression extractor = FactoryFeatureExtractor.nonmaxCandidate(
new ConfigExtract(localMaxRadius, minCounts, 0, false));
alg = new HoughTransformLineFootOfNorm(extractor,minDistanceFromOrigin);
derivX = gradient.getDerivativeType().createImage(1,1);
derivY = gradient.getDerivativeType().createImage(1, 1);
}
@Override
public List 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 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]);
}
// NOTE: angular accuracy is a function of range from sub image center. This pruning
// function uses a constant value for range accuracy. A custom algorithm should really
// be used here.
// NOTE: Thresholds should not be hardcoded...
post.pruneSimilar((float) (Math.PI * 0.04), 10, input.width, input.height);
post.pruneNBest(maxLines);
return post.createList();
}
public HoughTransformLineFootOfNorm getTransform() {
return alg;
}
public D getDerivX() {
return derivX;
}
public D getDerivY() {
return derivY;
}
public GrayF32 getEdgeIntensity() {
return intensity;
}
public GrayU8 getBinary() {
return binary;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy