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

boofcv.abst.feature.detect.extract.NonMaxLimiter 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: 1.1.7
Show newest version
/*
 * 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.extract;

import boofcv.struct.QueueCorner;
import boofcv.struct.image.GrayF32;
import georegression.struct.point.Point2D_I16;
import org.ddogleg.sorting.QuickSelect;
import org.ddogleg.struct.FastQueue;

/**
 * Adds the ability to specify the maximum number of points that you wish to return.  The selected
 * points will be sorted by feature intensity.  If maximums and minimums are found then the total
 * number refers to the total combined number of features.  The intensity that it sorts by is the absolute value.
 *
 * @author Peter Abeles
 */
public class NonMaxLimiter {
	NonMaxSuppression nonmax;

	int maxTotalFeatures;

	QueueCorner originalMin = new QueueCorner();
	QueueCorner originalMax = new QueueCorner();

	FastQueue localExtreme = new FastQueue<>(LocalExtreme.class, true);

	/**
	 * Configures the limiter
	 * @param nonmax Non-maximum suppression algorithm
	 * @param maxTotalFeatures The total number of allowed features it can return.  Set to a value ≤ 0 to disable.
	 */
	public NonMaxLimiter(NonMaxSuppression nonmax, int maxTotalFeatures) {
		this.nonmax = nonmax;
		if( maxTotalFeatures <= 0 )
			this.maxTotalFeatures = Integer.MAX_VALUE;
		else
			this.maxTotalFeatures = maxTotalFeatures;
	}

	/**
	 * Extracts local max and/or min from the intensity image.  If more than the maximum features are found then
	 * only the most intense ones will be returned
	 * @param intensity Feature image intensity
	 */
	public void process(GrayF32 intensity ) {

		originalMin.reset();
		originalMax.reset();
		nonmax.process(intensity,null,null,originalMin,originalMax);

		localExtreme.reset();
		for (int i = 0; i < originalMin.size; i++) {
			Point2D_I16 p = originalMin.get(i);
			float val = intensity.unsafe_get(p.x,p.y);
			localExtreme.grow().set(-val,false,p);
		}
		for (int i = 0; i < originalMax.size; i++) {
			Point2D_I16 p = originalMax.get(i);
			float val = intensity.unsafe_get(p.x, p.y);
			localExtreme.grow().set(val,true,p);
		}

		if( localExtreme.size > maxTotalFeatures ) {
			QuickSelect.select(localExtreme.data, maxTotalFeatures, localExtreme.size);
			localExtreme.size = maxTotalFeatures;
		}
	}

	public FastQueue getLocalExtreme() {
		return localExtreme;
	}

	public int getMaxTotalFeatures() {
		return maxTotalFeatures;
	}

	public void setMaxTotalFeatures(int maxTotalFeatures) {
		this.maxTotalFeatures = maxTotalFeatures;
	}

	public NonMaxSuppression getNonmax() {
		return nonmax;
	}

	/**
	 * Data structure which provides information on a local extremum.
	 */
	public static class LocalExtreme implements Comparable{
		/**
		 * Absolute value of image intensity
		 */
		public float intensity;
		public boolean max;
		public Point2D_I16 location;

		public LocalExtreme set( float intensity , boolean max , Point2D_I16 location ){
			this.intensity = intensity;
			this.max = max;
			this.location = location;
			return this;
		}

		/**
		 * Returns the value of the feature in the intensity image.  Adds the sign back
		 */
		public float getValue() {
			if( max )
				return intensity;
			else
				return -intensity;
		}

		@Override
		public int compareTo(LocalExtreme o) {
			if (intensity < o.intensity) {
				return 1;
			} else if( intensity > o.intensity ) {
				return -1;
			} else {
				return 0;
			}
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy