import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.Stroke; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import javax.swing.JFrame; import com.github.sarxos.webcam.Webcam; import com.github.sarxos.webcam.WebcamMotionDetector; import com.github.sarxos.webcam.WebcamMotionEvent; import com.github.sarxos.webcam.WebcamMotionListener; import com.github.sarxos.webcam.WebcamPanel; import com.github.sarxos.webcam.WebcamResolution; /** * This is example demonstrating how to use multipoint motion detection feature. * * @author tm1990 (https://github.com/tm1990) */ public class MultipointMotionDetectionExample implements WebcamMotionListener, WebcamPanel.Painter { public static void main(String[] args) throws InterruptedException { new MultipointMotionDetectionExample(); } private static final int INTERVAL = 100; // ms public static Webcam webcam; public static WebcamPanel.Painter painter = null; public MultipointMotionDetectionExample() { webcam = Webcam.getDefault(); webcam.setViewSize(WebcamResolution.VGA.getSize()); WebcamPanel panel = new WebcamPanel(webcam); panel.setPreferredSize(WebcamResolution.VGA.getSize()); panel.setPainter(this); panel.setFPSDisplayed(true); panel.setFPSLimited(true); panel.setFPSLimit(20); panel.setPainter(this); panel.start(); painter = panel.getDefaultPainter(); JFrame window = new JFrame("Multipoint-motion detection"); window.add(panel); window.setResizable(true); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.pack(); window.setVisible(true); WebcamMotionDetector detector = new WebcamMotionDetector(webcam); // Sets the max amount of motion points to 300 and the minimum range between them to 40 detector.setMaxMotionPoints(300); detector.setPointRange(40); detector.setInterval(INTERVAL); detector.addMotionListener(this); detector.start(); } /** * A HashMap to store all the current points and the current amount of times it has been * rendered. Time rendered is used to remove the point after a certain amount of time. */ public static HashMap<Point, Integer> motionPoints = new HashMap<Point, Integer>(); // Gets the motion points from the motion detector and adds it to the HashMap @Override public void motionDetected(WebcamMotionEvent wme) { for (Point p : wme.getPoints()) { motionPoints.put(p, 0); } } @Override public void paintPanel(WebcamPanel panel, Graphics2D g2) { if (painter != null) { painter.paintPanel(panel, g2); } } /** * Used to render the effect for the motion points. */ private static final Stroke STROKE = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1.0f, new float[] { 1.0f }, 0.0f); /** * The amount of time each point should be rendered for before being removed. */ public static final int renderTime = 3; /** * The actual size of the rendered effect for each point. */ public static final int renderSize = 20; @Override public void paintImage(WebcamPanel panel, BufferedImage image, Graphics2D g2) { if (painter != null) { painter.paintImage(panel, image, g2); } // Gets all the points and updates the amount of time they have been rendered for // And removes the ones that exceed the renderTime variable ArrayList<Point> rem = new ArrayList<Point>(); for (Map.Entry<Point, Integer> ent : motionPoints.entrySet()) { Point p = ent.getKey(); if (ent.getValue() != null) { int tt = ent.getValue(); if (tt >= renderTime) { rem.add(ent.getKey()); } else { int temp = ent.getValue() + 1; motionPoints.put(p, temp); } } } for (Point p : rem) { motionPoints.remove(p); } // Gets all the remaining points after removing the exceeded ones and then renders the // current ones as a red square for (Map.Entry<Point, Integer> ent : motionPoints.entrySet()) { Point p = ent.getKey(); int xx = p.x - (renderSize / 2), yy = p.y - (renderSize / 2); Rectangle bounds = new Rectangle(xx, yy, renderSize, renderSize); int dx = (int) (0.1 * bounds.width); int dy = (int) (0.2 * bounds.height); int x = bounds.x - dx; int y = bounds.y - dy; int w = bounds.width + 2 * dx; int h = bounds.height + dy; g2.setStroke(STROKE); g2.setColor(Color.RED); g2.drawRect(x, y, w, h); } } }