use of boofcv.struct.QueueCorner in project BoofCV by lessthanoptimal.
the class NonMaxCandidate_MT method examineMaximum.
@Override
protected void examineMaximum(GrayF32 intensityImage, ListIntPoint2D candidates, DogArray<Point2D_I16> found) {
found.reset();
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(), searches, (blockData, idx0, idx1) -> {
final Point2D_I16 pt = blockData.pt;
final QueueCorner threadCorners = blockData.corners;
final NonMaxCandidate.Search search = blockData.search;
threadCorners.reset();
search.initialize(intensityImage);
for (int candidateIdx = idx0; candidateIdx < idx1; candidateIdx++) {
candidates.get(candidateIdx, pt);
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.append(pt.x, pt.y);
}
});
// is required inside each thread
for (int i = 0; i < searches.size(); i++) {
found.copyAll(searches.get(i).corners.toList(), (src, dst) -> dst.setTo(src));
}
}
use of boofcv.struct.QueueCorner in project BoofCV by lessthanoptimal.
the class ExampleNonMaximumSupression method renderNonMax.
public static BufferedImage renderNonMax(GrayF32 intensity, int radius, float threshold) {
// Create and configure the feature detector
NonMaxSuppression nonmax = FactoryFeatureExtractor.nonmax(new ConfigExtract(radius, threshold));
// We will only searching for the maximums. Other variants will look for minimums or will exclude previous
// candidate detections from being detected twice
QueueCorner maximums = new QueueCorner();
nonmax.process(intensity, null, null, null, maximums);
// Visualize the intensity image
BufferedImage output = new BufferedImage(intensity.width, intensity.height, BufferedImage.TYPE_INT_RGB);
VisualizeImageData.colorizeSign(intensity, output, -1);
// render each maximum with a circle
Graphics2D g2 = output.createGraphics();
g2.setColor(Color.blue);
for (int i = 0; i < maximums.size(); i++) {
Point2D_I16 c = maximums.get(i);
VisualizeFeatures.drawCircle(g2, c.x, c.y, radius);
}
return output;
}
use of boofcv.struct.QueueCorner in project BoofCV by lessthanoptimal.
the class GeneralToInterestPoint method detect.
@Override
public void detect(T input) {
super.detect(input, null);
foundPoints.reset();
if (getDetector().isDetectMaximums()) {
QueueCorner corners = detector.getMaximums();
for (int i = 0; i < corners.size; i++) {
Point2D_I16 p = corners.get(i);
foundPoints.grow().setTo(p.x, p.y);
}
}
if (getDetector().isDetectMinimums()) {
QueueCorner corners = detector.getMinimums();
for (int i = 0; i < corners.size; i++) {
Point2D_I16 p = corners.get(i);
foundPoints.grow().setTo(p.x, p.y);
}
}
if (numSets == 2) {
// If there are two sets the maximums will be set 0 and minimums set 1
indexOfSetSplit = detector.getMaximums().size;
} else {
indexOfSetSplit = Integer.MAX_VALUE;
}
}
use of boofcv.struct.QueueCorner in project BoofCV by lessthanoptimal.
the class GenericNonMaxTests method compareToNaive.
/**
* Compares output against naive algorithm. Checks for compliance with sub-images
*/
@Test
void compareToNaive() {
GrayF32 inten = new GrayF32(width, height);
QueueCorner naiveMin = new QueueCorner(inten.getWidth() * inten.getHeight());
QueueCorner naiveMax = new QueueCorner(inten.getWidth() * inten.getHeight());
for (int useSubImage = 0; useSubImage <= 1; useSubImage++) {
// make sure it handles sub images correctly
if (useSubImage == 1) {
GrayF32 larger = new GrayF32(inten.width + 10, inten.height + 8);
inten = larger.subimage(5, 5, inten.width + 5, inten.height + 5, null);
}
for (int nonMaxWidth = 3; nonMaxWidth <= 9; nonMaxWidth += 2) {
int radius = nonMaxWidth / 2;
NonMaxExtractorNaive reg = new NonMaxExtractorNaive(strict);
reg.setSearchRadius(radius);
reg.setThreshold(0.6f);
for (int i = 0; i < 10; i++) {
ImageMiscOps.fillGaussian(inten, rand, 0, 3, -100, 100);
// detect the corners
findLocalPeaks(inten, 0.6f, radius, 0);
naiveMin.reset();
naiveMax.reset();
reg.process(inten, naiveMax);
PixelMath.negative(inten, inten);
reg.process(inten, naiveMin);
// check the number of corners
if (canDetectMin) {
assertTrue(foundMinimum.size() > 0);
assertEquals(naiveMin.size(), foundMinimum.size());
checkSamePoints(naiveMin, foundMinimum);
}
if (canDetectMax) {
assertTrue(foundMaximum.size() > 0);
assertEquals(naiveMax.size(), foundMaximum.size());
checkSamePoints(naiveMax, foundMaximum);
}
}
}
}
}
use of boofcv.struct.QueueCorner in project BoofCV by lessthanoptimal.
the class FeaturePyramid method detectCandidateFeatures.
/**
* Use the feature detector to find candidate features in each level. Only compute the needed image derivatives.
*/
private void detectCandidateFeatures(T image, double sigma) {
// adjust corner intensity threshold based upon the current scale factor
float scaleThreshold = (float) (baseThreshold / Math.pow(sigma, scalePower));
detector.setThreshold(scaleThreshold);
computeDerivative.setInput(image);
D derivX = null, derivY = null;
D derivXX = null, derivYY = null, derivXY = null;
if (detector.getRequiresGradient()) {
derivX = computeDerivative.getDerivative(true);
derivY = computeDerivative.getDerivative(false);
}
if (detector.getRequiresHessian()) {
derivXX = computeDerivative.getDerivative(true, true);
derivYY = computeDerivative.getDerivative(false, false);
derivXY = computeDerivative.getDerivative(true, false);
}
detector.process(image, derivX, derivY, derivXX, derivYY, derivXY);
intensities[spaceIndex].reshape(image.width, image.height);
intensities[spaceIndex].setTo(detector.getIntensity());
List<Point2D_I16> m = maximums[spaceIndex];
m.clear();
QueueCorner q = detector.getMaximums();
for (int i = 0; i < q.size; i++) {
m.add(q.get(i).copy());
}
spaceIndex++;
if (spaceIndex >= 3)
spaceIndex = 0;
}
Aggregations