private void selectBest(GrayF32 intensityImage, QueueCorner found , int numSelect, boolean positive) { if (numSelect > 0) { selectBest.setN(numSelect); selectBest.process(intensityImage, found,positive); QueueCorner best = selectBest.getBestCorners(); found.reset(); for( int i = 0; i < best.size; i++ ) { found.grow().set(best.get(i)); } } }
@Override public void updateGUI(BufferedImage guiImage, T origImage) { Graphics2D g2 = guiImage.createGraphics(); for (int i = 0; i < corners.size(); i++) { Point2D_I16 pt = corners.get(i); g2.setColor(Color.BLACK); g2.fillOval(pt.x - 4, pt.y - 4, 9, 9); g2.setColor(Color.RED); g2.fillOval(pt.x - 2, pt.y - 2, 5, 5); } if (panel == null) { panel = ShowImages.showWindow(guiImage, "Image Sequence"); addComponent(panel); } else { panel.setImage(guiImage); panel.repaint(); } }
/** * Selects pixels as corners which are above the threshold. */ public void process(GrayF32 intensity, QueueCorner corners ) { corners.reset(); float data[] = intensity.data; for( int y = 0; y < intensity.height; y++ ) { int startIndex = intensity.startIndex + y*intensity.stride; int endIndex = startIndex + intensity.width; for( int index = startIndex; index < endIndex; index++ ) { if( data[index] > thresh ) { int x = index-startIndex; corners.add(x,y); } } } }
@Override public void process(GrayU8 gray) { detector.process(gray); synchronized (lockGui) { maximumsGUI.reset(); minimumsGUI.reset(); if( detector.totalSets() == 1 ) { maximumsGUI.addAll(detector.getPointSet(0)); } else { minimumsGUI.addAll(detector.getPointSet(0)); maximumsGUI.addAll(detector.getPointSet(1)); } } } }
excludeList.reset(); for (int i = 0; i < active.size(); i++) { PyramidKltFeature f = active.get(i); excludeList.add((int) (f.x / scaleBottom), (int) (f.y / scaleBottom)); while( unused.size() < found.size() ) addTrackToUnused(); for (int i = 0; i < found.size() && !unused.isEmpty(); i++) { Point2D_I16 pt = found.get(i);
/** * 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; } }
/** * Searches for local maximas and converts into lines. * * @return Found lines in the image. */ public FastQueue<LineParametric2D_F32> extractLines() { lines.reset(); foundLines.reset(); foundIntensity.reset(); extractor.process(transform,null, candidates,null, foundLines); for( int i = 0; i < foundLines.size(); i++ ) { Point2D_I16 p = foundLines.get(i); int x0 = p.x - originX; int y0 = p.y - originY; if( Math.abs(x0) >= minDistanceFromOrigin || Math.abs(y0) >= minDistanceFromOrigin ) { LineParametric2D_F32 l = lines.grow(); l.p.set(p.x,p.y); l.slope.set(-y0,x0); foundIntensity.push(transform.get(p.x,p.y)); } } return lines; }
@Override public void onDraw(Canvas canvas, Matrix imageToView) { canvas.concat(imageToView); synchronized (lockGui) { for (int i = 0; i < maximumsGUI.size; i++) { Point2D_I16 p = maximumsGUI.get(i); canvas.drawCircle(p.x, p.y, radius, paintMax); } for (int i = 0; i < minimumsGUI.size; i++) { Point2D_I16 p = minimumsGUI.get(i); canvas.drawCircle(p.x, p.y, radius, paintMin); } } }
protected void checkLocalMax(int x_c, int y_c, float peakVal, GrayF32 img) { int x0 = x_c - radius; int x1 = x_c + radius; int y0 = y_c - radius; int y1 = y_c + radius; if (x0 < 0) x0 = 0; if (y0 < 0) y0 = 0; if (x1 >= img.width) x1 = img.width - 1; if (y1 >= img.height) y1 = img.height - 1; for (int y = y0; y <= y1; y++) { int index = img.startIndex + y * img.stride + x0; for (int x = x0; x <= x1; x++) { float v = img.data[index++]; if (v >= peakVal && !(x == x_c && y == y_c)) { // not a local max return; } } } // save location of local max localMax.add(x_c, y_c); }
/** * Computes the Hough transform using the image gradient and a binary image which flags pixels as being edges or not. * * @param derivX Image derivative along x-axis. * @param derivY Image derivative along y-axis. * @param binary Non-zero pixels are considered to be line pixels. */ public <D extends ImageGray> void transform(D derivX , D derivY , GrayU8 binary ) { InputSanityCheck.checkSameShape(derivX,derivY,binary); transform.reshape(derivX.width,derivY.height); ImageMiscOps.fill(transform,0); originX = derivX.width/2; originY = derivX.height/2; candidates.reset(); if( derivX instanceof GrayF32) _transform((GrayF32)derivX,(GrayF32)derivY,binary); else if( derivX instanceof GrayS16) _transform((GrayS16)derivX,(GrayS16)derivY,binary); else if( derivX instanceof GrayS32) _transform((GrayS32)derivX,(GrayS32)derivY,binary); else throw new IllegalArgumentException("Unsupported derivative image type: "+derivX.getClass().getSimpleName()); }
private void changeDetector(PointDetector fd) { detector = fd; sets.clear(); for (int i = 0; i < detector.totalSets(); i++) { sets.add( new QueueCorner()); } }
public final void add(int x, int y) { grow().set((short)x,(short)y); }
excludeList.reset(); for (int i = 0; i < active.size(); i++) { PyramidKltFeature f = active.get(i); excludeList.add((int) (f.x / scaleBottom), (int) (f.y / scaleBottom)); while( unused.size() < found.size() ) addTrackToUnused(); for (int i = 0; i < found.size() && !unused.isEmpty(); i++) { Point2D_I16 pt = found.get(i);
Point2D_I16 p = excludeMinimum.get(i); intensityImage.set(p.x,p.y,-Float.MAX_VALUE); Point2D_I16 p = excludeMaximum.get(i); intensityImage.set(p.x,p.y,Float.MAX_VALUE); foundMinimum.reset(); foundMaximum.reset(); if (intensity.hasCandidates()) { extractor.process(intensityImage, intensity.getCandidatesMin(), intensity.getCandidatesMax(),foundMinimum, foundMaximum);
/** * Searches for local maximas and converts into lines. * * @return Found lines in the image. */ public FastQueue<LineParametric2D_F32> extractLines() { lines.reset(); foundLines.reset(); foundIntensity.reset(); extractor.process(transform, null,null,null, foundLines); int w2 = transform.width/2; for( int i = 0; i < foundLines.size(); i++ ) { Point2D_I16 p = foundLines.get(i); float r = (float)(r_max*(p.x-w2)/w2); float c = tableTrig.c[p.y]; float s = tableTrig.s[p.y]; float x0 = r*c+originX; float y0 = r*s+originY; foundIntensity.push( transform.get(p.x,p.y)); LineParametric2D_F32 l = lines.grow(); l.p.set(x0,y0); l.slope.set(-s,c); Point2D_F64 p2 = new Point2D_F64(); lineToCoordinate(l,p2); } return lines; }
@Override public void detect(T input) { foundMin.reset(); foundMax.reset(); detector.detect(input,null); QueueCorner min = detector.getMinimums(); for( int i = 0; i < min.size; i++ ) { Point2D_I16 p = min.get(i); foundMin.grow().set(p.x,p.y); } QueueCorner max = detector.getMaximums(); for( int i = 0; i < max.size; i++ ) { Point2D_I16 p = max.get(i); foundMax.grow().set(p.x,p.y); } }
@Override public void processImage(int sourceID, long frameID, final BufferedImage buffered, ImageBase input) { if( detectorChanged ) { detectorChanged = false; // this can be done safely outside of the GUI thread controls.comboActions.get( controls.selectedAlgorithm ).run(); } final double seconds; long timeBefore = System.nanoTime(); detector.process((T)input); long timeAfter = System.nanoTime(); seconds = (timeAfter-timeBefore)*1e-9; synchronized (featureLock) { for (int i = 0; i < detector.totalSets(); i++) { QueueCorner src = detector.getPointSet(i); QueueCorner dst = sets.get(i); dst.reset(); dst.addAll(src); } } BoofSwingUtil.invokeNowOrLater(() -> { controls.setProcessingTime(seconds); imagePanel.setBufferedImage(buffered); imagePanel.repaint(); }); }
protected void checkLocalMin( int x_c , int y_c , float peakVal , GrayF32 img ) { int x0 = x_c-radius; int x1 = x_c+radius; int y0 = y_c-radius; int y1 = y_c+radius; if (x0 < 0) x0 = 0; if (y0 < 0) y0 = 0; if (x1 >= img.width) x1 = img.width - 1; if (y1 >= img.height) y1 = img.height - 1; for( int y = y0; y <= y1; y++ ) { int index = img.startIndex + y*img.stride+x0; for( int x = x0; x <= x1; x++ ) { float v = img.data[index++]; if( v < peakVal ) { // not a local minimum return; } } } localMin.add(x_c,y_c); }
public SelectNBestFeatures(int N) { bestCorners = new QueueCorner(N); setN(N); }
public final void add( Point2D_I16 pt ) { grow().set(pt.x, pt.y); } }