diff --git a/README.md b/README.md index 38c10a7e..838a66d4 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,7 @@ Below are the very pretty basic examples demonstrating of how Webcam Capture API * [How to save captured image in PNG / JPG / GIF / BMP etc](https://github.com/sarxos/webcam-capture/blob/master/webcam-capture/src/example/java/DifferentFileFormatsExample.java) * [How to capture with many parallel threads](https://github.com/sarxos/webcam-capture/blob/master/webcam-capture/src/example/java/ConcurrentThreadsExample.java) * [How to detect motion (text mode only)](https://github.com/sarxos/webcam-capture/blob/master/webcam-capture/src/example/java/DetectMotionExample.java) +* [How to perform multipoint motion detection](https://github.com/sarxos/webcam-capture/blob/master/webcam-capture/src/example/java/MultipointMotionDetectionExample.java) * [How to display images from multiple IP cameras exposing pictures in JPG format](https://github.com/sarxos/webcam-capture/blob/master/webcam-capture-drivers/driver-ipcam/src/examples/java/JpegDasdingStudioExample.java) * [How to display image from IP camera exposing MJPEG stream](https://github.com/sarxos/webcam-capture/blob/master/webcam-capture-drivers/driver-ipcam/src/examples/java/MjpegLignanoBeachExample.java) * [How to use composite driver to display both, build-in and IP camera images](https://github.com/sarxos/webcam-capture/blob/master/webcam-capture-drivers/driver-ipcam/src/examples/java/DualNativeAndMjpegWebcamExample.java) diff --git a/webcam-capture/src/example/java/MultipointMotionDetectionExample.java b/webcam-capture/src/example/java/MultipointMotionDetectionExample.java index 88512e94..5a03bec2 100644 --- a/webcam-capture/src/example/java/MultipointMotionDetectionExample.java +++ b/webcam-capture/src/example/java/MultipointMotionDetectionExample.java @@ -1,142 +1,163 @@ -package com.github.sarxos.webcam; - -import javax.swing.*; -import java.awt.*; +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; -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(); +import javax.swing.JFrame; - JFrame window = new JFrame("Multipoint-motion detection"); - window.add(panel); - window.setResizable(true); - window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - window.pack(); - window.setVisible(true); +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; - 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 motionPoints = new HashMap(); - - //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); - } - } +/** + * This is example demonstrating how to use multipoint motion detection feature. + * + * @author tm1990 (https://github.com/tm1990) + */ +public class MultipointMotionDetectionExample implements WebcamMotionListener, WebcamPanel.Painter { - @Override - public void paintPanel(WebcamPanel panel, Graphics2D g2) { - if (painter != null) { - painter.paintPanel(panel, g2); - } - } + 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; - //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); + public MultipointMotionDetectionExample() { + + webcam = Webcam.getDefault(); + webcam.setViewSize(WebcamResolution.VGA.getSize()); - //The amount of time each point should be rendered for before being removed - public static final int renderTime = 3; + 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(); - //The actual size of the rendered effect for each point - public static final int renderSize = 20; + painter = panel.getDefaultPainter(); - @Override - public void paintImage(WebcamPanel panel, BufferedImage image, Graphics2D g2) { + 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); - if (painter != null) { - painter.paintImage(panel, image, g2); - } + // Sets the max amount of motion points to 300 and the minimum range between them to 40 + detector.setMaxMotionPoints(300); + detector.setPointRange(40); - //Gets all the points and updates the amount of time they have been rendered for - //And removes the ones that exceed the renderTime variable + detector.setInterval(INTERVAL); + detector.addMotionListener(this); - ArrayList rem = new ArrayList(); + detector.start(); + } - for (Map.Entry ent : motionPoints.entrySet()) { - Point p = ent.getKey(); + /** + * 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 motionPoints = new HashMap(); - if (ent.getValue() != null) { - int tt = ent.getValue(); - if (tt >= renderTime) { - rem.add(ent.getKey()); + // 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); + } + } - } else { - int temp = ent.getValue() + 1; - motionPoints.put(p, temp); - } + @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); - for(Point p : rem){ - motionPoints.remove(p); - } + /** + * 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; - //Gets all the remaining points after removing the exceeded ones and then renders the current ones as a red square - for(Map.Entry ent : motionPoints.entrySet()){ - Point p = ent.getKey(); + @Override + public void paintImage(WebcamPanel panel, BufferedImage image, Graphics2D g2) { - int xx = p.x - (renderSize / 2), yy = p.y - (renderSize / 2); + if (painter != null) { + painter.paintImage(panel, image, g2); + } - Rectangle bounds = new Rectangle(xx, yy, renderSize, renderSize); + // Gets all the points and updates the amount of time they have been rendered for + // And removes the ones that exceed the renderTime variable - int dx = (int) (0.1 * bounds.width); - int dy = (int) (0.2 * bounds.height); - int x = (int) bounds.x - dx; - int y = (int) bounds.y - dy; - int w = (int) bounds.width + 2 * dx; - int h = (int) bounds.height + dy; + ArrayList rem = new ArrayList(); - g2.setStroke(STROKE); - g2.setColor(Color.RED); - g2.drawRect(x, y, w, h); + for (Map.Entry 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 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); + } + } }