package org.myrobotlab.boofcv; import boofcv.abst.tracker.TrackerObjectQuad; import boofcv.factory.tracker.FactoryTrackerObjectQuad; import boofcv.io.image.ConvertBufferedImage; import boofcv.io.webcamcapture.UtilWebcamCapture; import boofcv.struct.image.GrayU8; import boofcv.struct.image.ImageBase; import com.github.sarxos.webcam.Webcam; import georegression.geometry.UtilPolygons2D_F64; import georegression.struct.point.Point2D_I32; import georegression.struct.shapes.Quadrilateral_F64; import georegression.struct.shapes.Rectangle2D_F64; import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.image.BufferedImage; import org.myrobotlab.service.BoofCv; import org.myrobotlab.service.data.Point2Df; public class ObjectTracker<T extends ImageBase> extends JPanel implements MouseListener, MouseMotionListener { /** * */ private static final long serialVersionUID = 1L; BoofCv myService = null; TrackerObjectQuad<T> tracker; // location of the target being tracked Quadrilateral_F64 target = new Quadrilateral_F64(); // location selected by the mouse Point2D_I32 point0 = new Point2D_I32(); Point2D_I32 point1 = new Point2D_I32(); int desiredWidth, desiredHeight; volatile int mode = 0; BufferedImage workImage; Point2Df rectangleCenter = new Point2Df(0.0f, 0.0f); JFrame window; /** * Configures the tracking application * * @param tracker * The object tracker * @param desiredWidth * Desired size of the input stream * @param desiredHeight * Desired height of the input stream */ public ObjectTracker(TrackerObjectQuad<T> tracker, int desiredWidth, int desiredHeight) { this.tracker = tracker; this.desiredWidth = desiredWidth; this.desiredHeight = desiredHeight; addMouseListener(this); addMouseMotionListener(this); window = new JFrame("Object Tracking"); window.setContentPane(this); window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } /** * Invoke to start the main processing loop. */ public void process() { Webcam webcam = UtilWebcamCapture.openDefault(desiredWidth, desiredHeight); // Mapper mapperX = new Mapper(0,desiredWidth,0.0,1.0); // adjust the window size and let the GUI know it has changed Dimension actualSize = webcam.getViewSize(); setPreferredSize(actualSize); setMinimumSize(actualSize); window.setMinimumSize(actualSize); window.setPreferredSize(actualSize); window.setVisible(true); // create T input = tracker.getImageType().createImage(actualSize.width, actualSize.height); workImage = new BufferedImage(input.getWidth(), input.getHeight(), BufferedImage.TYPE_INT_RGB); while (true) { BufferedImage buffered = webcam.getImage(); ConvertBufferedImage.convertFrom(webcam.getImage(), input, true); // mode is read/written to by the GUI also int mode = this.mode; boolean success = false; if (mode == 2) { Rectangle2D_F64 rect = new Rectangle2D_F64(); rect.set(point0.x, point0.y, point1.x, point1.y); UtilPolygons2D_F64.convert(rect, target); success = tracker.initialize(input, target); this.mode = success ? 3 : 0; } else if (mode == 3) { success = tracker.process(input, target); } synchronized (workImage) { // copy the latest image into the work buffered Graphics2D g2 = workImage.createGraphics(); g2.drawImage(buffered, 0, 0, null); // visualize the current results if (mode == 1) { drawSelected(g2); } else if (mode == 3) { if (success) { drawTrack(g2); } } } repaint(); } } @Override public void paint(Graphics g) { if (workImage != null) { // draw the work image and be careful to make sure it isn't being // manipulated at the same time synchronized (workImage) { ((Graphics2D) g).drawImage(workImage, 0, 0, null); } } } private void drawSelected(Graphics2D g2) { g2.setColor(Color.RED); g2.setStroke(new BasicStroke(3)); g2.drawLine(point0.getX(), point0.getY(), point1.getX(), point0.getY()); g2.drawLine(point1.getX(), point0.getY(), point1.getX(), point1.getY()); g2.drawLine(point1.getX(), point1.getY(), point0.getX(), point1.getY()); g2.drawLine(point0.getX(), point1.getY(), point0.getX(), point0.getY()); } private void drawTrack(Graphics2D g2) { g2.setStroke(new BasicStroke(3)); g2.setColor(Color.RED); g2.drawLine((int) target.a.getX(), (int) target.a.getY(), (int) target.b.getX(), (int) target.b.getY()); g2.setColor(Color.BLUE); g2.drawLine((int) target.b.getX(), (int) target.b.getY(), (int) target.c.getX(), (int) target.c.getY()); g2.setColor(Color.GREEN); g2.drawLine((int) target.c.getX(), (int) target.c.getY(), (int) target.d.getX(), (int) target.d.getY()); g2.setColor(Color.DARK_GRAY); g2.drawLine((int) target.d.getX(), (int) target.d.getY(), (int) target.a.getX(), (int) target.a.getY()); rectangleCenter.x = (float) (target.a.getX() + ((target.b.getX() - target.a.getX()) / 2)); rectangleCenter.y = (float) (target.a.getY() + ((target.d.getY() - target.a.getY()) / 2)); System.out.println(rectangleCenter.x + " , " + rectangleCenter.y); } // not used, commented out. // private void drawTarget( Graphics2D g2 ) { // g2.setColor(Color.RED); // g2.setStroke( new BasicStroke(2)); // g2.drawLine(point0.getX(),point0.getY(),point1.getX(),point0.getY()); // g2.drawLine(point1.getX(),point0.getY(),point1.getX(),point1.getY()); // g2.drawLine(point1.getX(),point1.getY(),point0.getX(),point1.getY()); // g2.drawLine(point0.getX(),point1.getY(),point0.getX(),point0.getY()); // } @Override public void mousePressed(MouseEvent e) { point0.set(e.getX(), e.getY()); point1.set(e.getX(), e.getY()); mode = 1; } @Override public void mouseReleased(MouseEvent e) { point1.set(e.getX(), e.getY()); mode = 2; } @Override public void mouseClicked(MouseEvent e) { mode = 0; } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mouseDragged(MouseEvent e) { if (mode == 1) { point1.set(e.getX(), e.getY()); } } @Override public void mouseMoved(MouseEvent e) { } public static void main(String[] args) { // ImageType<Planar<GrayU8>> colorType = ImageType.pl(3,GrayU8.class); TrackerObjectQuad<GrayU8> tracker = // FactoryTrackerObjectQuad.circulant(null, GrayU8.class); // FactoryTrackerObjectQuad.sparseFlow(null,GrayU8.class,null); FactoryTrackerObjectQuad.tld(null, GrayU8.class); // FactoryTrackerObjectQuad.meanShiftComaniciu2003(new // ConfigComaniciu2003(), colorType); // FactoryTrackerObjectQuad.meanShiftComaniciu2003(new // ConfigComaniciu2003(true),colorType); // FactoryTrackerObjectQuad.meanShiftLikelihood(30,5,255, // MeanShiftLikelihoodType.HISTOGRAM,colorType); ObjectTracker<GrayU8> app = new ObjectTracker<GrayU8>(tracker, 640, 480); app.process(); } }