Skip to content

Commit

Permalink
Motion detector example
Browse files Browse the repository at this point in the history
  • Loading branch information
sarxos committed Nov 18, 2012
1 parent adc93ca commit 26b47d6
Show file tree
Hide file tree
Showing 15 changed files with 250 additions and 33 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@
<module>webcam-capture-driver-ipcam</module>
<module>webcam-capture-driver-jmf</module>
<!-- below ones cannot be released since all of them require external 3rd-party repos -->
<!--
<module>webcam-capture-driver-civil</module>
<module>webcam-capture-driver-openimaj</module>
<module>webcam-capture-driver-vlcj</module>
<module>webcam-capture-driver-javacv</module>
-->
<module>webcam-capture-examples</module>
<module>webcam-capture-pages</module>
</modules>

<properties>
Expand Down
23 changes: 23 additions & 0 deletions webcam-capture-examples/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.github.sarxos</groupId>
<artifactId>webcam-capture-parent</artifactId>
<version>0.3.5</version>
</parent>

<artifactId>webcam-capture-examples</artifactId>
<packaging>pom</packaging>

<name>Webcam Capture Examples</name>
<description>Parent POM for Webcam Capture examples set</description>

<modules>
<module>webcam-capture-applet</module>
<module>webcam-capture-motiondetector</module>
</modules>

</project>
2 changes: 1 addition & 1 deletion webcam-capture-examples/webcam-capture-applet/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<parent>
<groupId>com.github.sarxos</groupId>
<artifactId>webcam-capture-parent</artifactId>
<artifactId>webcam-capture-examples</artifactId>
<version>0.3.5</version>
</parent>

Expand Down
31 changes: 31 additions & 0 deletions webcam-capture-examples/webcam-capture-motiondetector/.classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
23 changes: 23 additions & 0 deletions webcam-capture-examples/webcam-capture-motiondetector/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>webcam-capture-example-motiondetector</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
17 changes: 17 additions & 0 deletions webcam-capture-examples/webcam-capture-motiondetector/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Webcam Capture Motion Detector Example

This is simple application illustrating of how to use build-in motion detector.

## Detect Motion

Detector use data from webcam and perform numeric analysis to decide if there
is a motion, or there is none.

This sample application uses ```while / isMotion()``` approach (the second way
to use motion detector is listener approach). It display Me Gusta Guy when motion
has been detected and Forever Alone Guy when no motion has been detected. In this
example motion inertia is 1000 milliseconds.

Some screenshoots:


51 changes: 51 additions & 0 deletions webcam-capture-examples/webcam-capture-motiondetector/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.github.sarxos</groupId>
<artifactId>webcam-capture-examples</artifactId>
<version>0.3.5</version>
</parent>

<artifactId>webcam-capture-example-motiondetector</artifactId>
<packaging>jar</packaging>

<name>Webcam Capture - Motion Detector Example</name>
<description>Example of how to use Webcam Capture motion detector</description>

<dependencies>
<dependency>
<groupId>com.github.sarxos</groupId>
<artifactId>webcam-capture</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.0</version>
<configuration>
<artifactSet>
<includes>
<include>*:*</include>
</includes>
</artifactSet>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.github.sarxos.webcam;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;


/**
* Detect motion.
*
* @author Bartosz Firyn (SarXos)
*/
public class DetectMotionExample extends JFrame implements Runnable {

/**
*
*/
private static final long serialVersionUID = -585739158170333370L;

private static final int INTERVAL = 100; // ms

private ImageIcon motion = null;
private ImageIcon nothing = null;
private JLabel label = null;

private Webcam webcam = Webcam.getDefault();
private int threshold = WebcamMotionDetector.DEFAULT_THREASHOLD;
private int inertia = 1000; // how long motion is valid

public DetectMotionExample() {

try {
motion = new ImageIcon(ImageIO.read(getClass().getResourceAsStream("/me-gusta.png")));
nothing = new ImageIcon(ImageIO.read(getClass().getResourceAsStream("/forever-alone.png")));
} catch (IOException e) {
e.printStackTrace();
}

label = new JLabel(nothing);

Thread updater = new Thread(this, "updater-thread");
updater.setDaemon(true);
updater.start();

setTitle("Rage Motion Detector");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());

webcam.setViewSize(new Dimension(320, 240));

WebcamPanel panel = new WebcamPanel(webcam);
panel.setFPS(4);

add(panel);
add(label);

pack();
setVisible(true);
}

public static void main(String[] args) throws InterruptedException {
new DetectMotionExample();
}

@Override
public void run() {

WebcamMotionDetector detector = new WebcamMotionDetector(webcam, threshold, inertia);
detector.setInterval(INTERVAL);
detector.start();

while (true) {

Icon icon = label.getIcon();
if (detector.isMotion()) {
if (icon != motion) {
label.setIcon(motion);
}
} else {
if (icon != nothing) {
label.setIcon(nothing);
}
}

try {
Thread.sleep(INTERVAL * 2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

This file was deleted.

2 changes: 1 addition & 1 deletion webcam-capture/src/example/resources/logback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</layout>
</appender>

<root level="debug">
<root level="error">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public class WebcamMotionDetector {

private static final Logger LOG = LoggerFactory.getLogger(WebcamMotionDetector.class);

public static final int DEFAULT_THREASHOLD = 25;

/**
* Create new threads for detector internals.
*
Expand Down Expand Up @@ -179,7 +181,7 @@ public WebcamMotionDetector(Webcam webcam, int threshold) {
* @param webcam web camera instance
*/
public WebcamMotionDetector(Webcam webcam) {
this(webcam, 25, 0);
this(webcam, DEFAULT_THREASHOLD, 0);
}

public void start() {
Expand Down

8 comments on commit 26b47d6

@settaratici
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi sarxos,

how can i check previous detected motion's time ?
pls help me..

@sarxos
Copy link
Owner Author

@sarxos sarxos commented on 26b47d6 Aug 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not add WebcamMotionListener and store timestamp on motionDetected(..) to be read later?

https://github.com/sarxos/webcam-capture/blob/master/webcam-capture/src/example/java/DetectMotionExample.java

@settaratici
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, i want to check if motion is finished and check if inertia is fine take a snapshot..

@sarxos
Copy link
Owner Author

@sarxos sarxos commented on 26b47d6 Aug 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Detector is doing this inside. What you want is probably:

Webcam webcam = Webcam.getDefault();

WebcamMotionDetector detector = new WebcamMotionDetector(webcam);
detector.setInertia(2000); // set inertia time to e.g. 2 seconds
detector.setInterval(100); // check motion once per 100 ms

// this will be true for 2 seconds from the last motion detection (inertia time)
while (detector.isMotion()) { 
    Thread.sleep(100);
}

image = webcam.getImage();

@settaratici
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By this way we cannot learn "no-motion".

        Webcam webcam = Webcam.getWebcams().get(1);
    WebcamMotionDetector detector = new WebcamMotionDetector(webcam);
    detector.setInterval(1000);
            detector.setInertia(500);
    detector.start();


    while (true)
    {
        if (detector.isMotion())
        {
            // motion detected
        }
        else
        {
            // motion finished and 
    // if inertia after motion is greater than 500 ms
    // get image 
        }


    }

@sarxos
Copy link
Owner Author

@sarxos sarxos commented on 26b47d6 Aug 7, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not? This is exactly what you are doing. When detector.isMotion() is false after it was true before, we know for sure that there was no motion in last 500 ms.

The only invalid thing in your case is interval vs inertia setting because interval MUST be at least 2x smaller than inertia (because motion sampling can be treated as a discrete signal which must be processed in accordance to Nyquist–Shannon theorem). In other words, when the above is not true, for time t = interval - inertia, if and only if it is positive, detector will be in state when motion has been already forgotten (due to inertia time), but the next check will be in t, so someone can move, and detector will not be able to detect this.

The meaning of both these settings is:

  • interval = delay between consecutive checks validating if there is a motion on image (1 / interval = sampling rate)
  • inertia = for how long, after motion has been detected, it stays in such state (i.e. return true on isMotion() calls)
Webcam webcam = Webcam.getWebcams().get(1);
WebcamMotionDetector detector = new WebcamMotionDetector(webcam);
detector.setInterval(100); // do motion check once per 100 ms
detector.setInertia(2000); // remember motion for 2000 ms
detector.start();

boolean motion = false;

while (true) {
  if (detector.isMotion()) {
    motion = true;
  } else {
    if (motion) {
      // there was no-motion in last 2000 ms, but before this there was some motion
      // get image
      motion = false;
    }
  }
  Thread.sleep(10); // MUST be much smaller than interval
}

@sarxos
Copy link
Owner Author

@sarxos sarxos commented on 26b47d6 Aug 8, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@settaratici, if you had problems with motion detection and false positives this may be caused by #250 I just fixed. Because of this bug there can be false no-motion moments detected.

The newest snapshot JAR already contain the fix. You can found it here:

webcam-capture-0.3.10-SNAPSHOT.jar

Please check and verify against your code. Moreover, I crafted small example to demonstrate how to detect "motion begin" and "motion end" moments using loop and custom inertia time. This example can be found here:

DetectMotionEventsExample.java

@settaratici
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works fine. Thank you :)) Now, i can check if motion is finished.

Please sign in to comment.