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

boofcv.alg.feature.detect.extract.NonMaxCandidate_MT 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-2019, 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.feature.detect.extract;

import boofcv.concurrency.BoofConcurrency;
import boofcv.struct.QueueCorner;
import boofcv.struct.image.GrayF32;
import georegression.struct.point.Point2D_I16;

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

/**
 * Concurrent implementation of {@link NonMaxCandidate}.
 *
 *
 * @author Peter Abeles
 */
public class NonMaxCandidate_MT extends NonMaxCandidate {

	final Object lock = new Object();
	final List searches = new ArrayList<>();
	final List cornerLists = new ArrayList<>();

	public NonMaxCandidate_MT(Search search) {
		super(search);
	}

	@Override
	protected void examineMinimum(GrayF32 intensityImage , QueueCorner candidates , QueueCorner found ) {
		final int stride = intensityImage.stride;
		final float inten[] = intensityImage.data;

		// little cost to creating a thread so let it select the minimum block size
		BoofConcurrency.loopBlocks(0,candidates.size,(idx0,idx1)->{
			NonMaxCandidate.Search search;
			QueueCorner threadCorners;
			synchronized ( lock ) {
				search = searches.isEmpty() ? this.search.newInstance() : searches.remove(searches.size()-1);
				threadCorners = cornerLists.isEmpty() ? new QueueCorner() : cornerLists.remove(cornerLists.size()-1);
				threadCorners.reset();
			}
			search.initialize(intensityImage);

			for (int iter = idx0; iter < idx1; iter++) {
				Point2D_I16 pt = candidates.data[iter];

				if( pt.x < ignoreBorder || pt.y < ignoreBorder || pt.x >= endBorderX || pt.y >= endBorderY)
					continue;

				int center = intensityImage.startIndex + pt.y * stride + pt.x;

				float val = inten[center];
				if (val > thresholdMin || val == -Float.MAX_VALUE ) continue;

				int x0 = Math.max(0,pt.x - radius);
				int y0 = Math.max(0,pt.y - radius);
				int x1 = Math.min(intensityImage.width, pt.x + radius + 1);
				int y1 = Math.min(intensityImage.height, pt.y + radius + 1);

				if( search.searchMin(x0,y0,x1,y1,center,val) )
					threadCorners.add(pt.x,pt.y);
			}

			synchronized (lock) {
				found.addAll(threadCorners);
				searches.add(search);
				cornerLists.add(threadCorners);
			}
		});
	}

	@Override
	protected void examineMaximum(GrayF32 intensityImage , QueueCorner candidates , QueueCorner found ) {
		final int stride = intensityImage.stride;
		final float inten[] = intensityImage.data;

		// little cost to creating a thread so let it select the minimum block size
		BoofConcurrency.loopBlocks(0,candidates.size,(idx0,idx1)-> {
			NonMaxCandidate.Search search;
			QueueCorner threadCorners;
			synchronized ( lock ) {
				search = searches.isEmpty() ? this.search.newInstance() : searches.remove(searches.size()-1);
				threadCorners = cornerLists.isEmpty() ? new QueueCorner() : cornerLists.remove(cornerLists.size()-1);
				threadCorners.reset();
			}
			search.initialize(intensityImage);

			for (int iter = idx0; iter < idx1; iter++) {
				Point2D_I16 pt = candidates.data[iter];

				if (pt.x < ignoreBorder || pt.y < ignoreBorder || pt.x >= endBorderX || pt.y >= endBorderY)
					continue;

				int center = intensityImage.startIndex + pt.y * stride + pt.x;

				float val = inten[center];
				if (val < thresholdMax || val == Float.MAX_VALUE) continue;

				int x0 = Math.max(0, pt.x - radius);
				int y0 = Math.max(0, pt.y - radius);
				int x1 = Math.min(intensityImage.width, pt.x + radius + 1);
				int y1 = Math.min(intensityImage.height, pt.y + radius + 1);

				if (search.searchMax(x0, y0, x1, y1, center, val))
					threadCorners.add(pt.x, pt.y);
			}

			synchronized (lock) {
				found.addAll(threadCorners);
				searches.add(search);
				cornerLists.add(threadCorners);
			}
		});
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy