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

boofcv.alg.tracker.tld.TldNonMaximalSuppression 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-2015, 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.alg.tracker.tld;

import org.ddogleg.struct.FastQueue;

/**
 * Performs non-maximum suppression on high confidence detected regions.  A graph of connected regions is constructed.
 * Two regions are considered connected if their overlap is above a threshold.  A region is considered a local maximum
 * if it has a score higher than all its neighbors.  A weighted average is computed using all regions connected to
 * the local maximum.
 *
 * NOTE: This is a completely different non-maximum algorithm from what was described in the paper.  The algorithm
 * described in the paper only approximates non-maximum suppression.
 *
 * @author Peter Abeles
 */
public class TldNonMaximalSuppression {

	// cut off for connecting two nodes
	private double connectionThreshold;

	// connection graph
	private FastQueue conn = new FastQueue(Connections.class,true);

	// used for computing the overlap between two regions
	private TldHelperFunctions helper = new TldHelperFunctions();

	/**
	 * Configures non-maximum suppression
	 *
	 * @param connectionThreshold Two regions are considered connected of their overlap is ≥ to this value.
	 *                               0 to 1.0. A value of 0.5 is recommended
	 */
	public TldNonMaximalSuppression(double connectionThreshold) {
		this.connectionThreshold = connectionThreshold;
	}

	/**
	 * Finds local maximums from the set of provided regions
	 *
	 * @param regions Set of high confidence regions for target
	 * @param output Output after non-maximum suppression
	 */
	public void process( FastQueue regions , FastQueue output ) {

		final int N = regions.size;

		// set all connections to be a local maximum initially
		conn.growArray(N);
		for( int i = 0; i < N; i++ ) {
			conn.data[i].reset();
		}

		// Create the graph of connected regions and mark which regions are local maximums
		for( int i = 0; i < N; i++ ) {
			TldRegion ra = regions.get(i);
			Connections ca = conn.data[i];

			for( int j = i+1; j < N; j++ ) {
				TldRegion rb = regions.get(j);
				Connections cb = conn.data[j];

				// see if they are connected
				double overlap = helper.computeOverlap(ra.rect,rb.rect);
				if( overlap < connectionThreshold ) {
					continue;
				}

				// connect the two and check for strict maximums
				ca.maximum &= ra.confidence > rb.confidence;
				cb.maximum &= rb.confidence > ra.confidence;
				ra.connections++;
				rb.connections++;
			}
		}

		// Compute the output from local maximums.
		for( int i = 0; i < N; i++ ) {
			TldRegion ra = regions.get(i);
			Connections ca = conn.data[i];

			if( ca.maximum ) {
				TldRegion o = output.grow();
				o.connections = ra.connections;
				o.confidence = ra.confidence;
				o.rect.set(ra.rect);
			} else if( ra.connections == 0 ) {
				System.out.println("Not a maximum but has zero connections?");
			}
		}
	}

	public FastQueue getConnections() {
		return conn;
	}

	/**
	 * Contains connection information for a specific rectangular region
	 */
	public static class Connections
	{
		// if true then it's a local maximum
		boolean maximum;

		public void reset() {
			maximum = true;
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy