Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for multiple points for source of motion #350

Merged
merged 2 commits into from
Jun 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions webcam-capture/src/example/java/MultipointMotionDetectionExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package com.github.sarxos.webcam;

import javax.swing.*;
import java.awt.*;
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();

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 = (int) bounds.x - dx;
int y = (int) bounds.y - dy;
int w = (int) bounds.width + 2 * dx;
int h = (int) bounds.height + dy;

g2.setStroke(STROKE);
g2.setColor(Color.RED);
g2.drawRect(x, y, w, h);

}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ protected void detect() {
* @param image with the motion detected
*/
private void notifyMotionListeners(BufferedImage currentOriginal) {
WebcamMotionEvent wme = new WebcamMotionEvent(this, previousOriginal, currentOriginal, detectorAlgorithm.getArea(), detectorAlgorithm.getCog());
WebcamMotionEvent wme = new WebcamMotionEvent(this, previousOriginal, currentOriginal, detectorAlgorithm.getArea(), detectorAlgorithm.getCog(), detectorAlgorithm.getPoints());
for (WebcamMotionListener l : listeners) {
try {
l.motionDetected(wme);
Expand Down Expand Up @@ -437,4 +437,22 @@ public WebcamMotionDetectorAlgorithm getDetectorAlgorithm() {
return detectorAlgorithm;
}


public void setMaxMotionPoints(int i){
detectorAlgorithm.setMaxPoints(i);
}

public int getMaxMotionPoints(){
return detectorAlgorithm.getMaxPoints();
}


public void setPointRange(int i){
detectorAlgorithm.setPointRange(i);
}

public int getPointRange(){
return detectorAlgorithm.getPointRange();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.awt.Point;
import java.awt.image.BufferedImage;
import java.util.ArrayList;


/**
Expand Down Expand Up @@ -50,4 +51,36 @@ public interface WebcamMotionDetectorAlgorithm {
* @return Return percentage image fraction covered by motion
*/
double getArea();

/**
* Set the minimum range between each point detected
* @param i the range to set
*/
void setPointRange(int i);

/**
* Set the max amount of points that can be detected at one time
* @param i The amount of points that can be detected
*/
void setMaxPoints(int i);


/**
* Get the current minimum range between each point
* @return The current range
*/
int getPointRange();

/**
* Get the current max amount of points that can be detected at one time
* @return
*/
int getMaxPoints();


/**
* Returns the currently stored points that have been detected
* @return The current points
*/
ArrayList<Point> getPoints();
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.github.sarxos.webcam;

import java.awt.Point;
import java.awt.image.BufferedImage;

import com.github.sarxos.webcam.util.jh.JHBlurFilter;
import com.github.sarxos.webcam.util.jh.JHGrayFilter;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

/**
* Default motion detector algorithm.
*/
Expand Down Expand Up @@ -71,6 +72,7 @@ public BufferedImage prepareImage(BufferedImage original) {

@Override
public boolean detect(BufferedImage previousModified, BufferedImage currentModified) {
points.clear();
int p = 0;

int cogX = 0;
Expand All @@ -79,6 +81,7 @@ public boolean detect(BufferedImage previousModified, BufferedImage currentModif
int w = currentModified.getWidth();
int h = currentModified.getHeight();

int j = 0;
if (previousModified != null) {
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
Expand All @@ -88,10 +91,29 @@ public boolean detect(BufferedImage previousModified, BufferedImage currentModif
int pid = combinePixels(cpx, ppx) & 0x000000ff;

if (pid >= pixelThreshold) {
cogX += x;
cogY += y;
p += 1;
}
Point pp = new Point(x, y);
boolean keep = j < maxPoints;

if (keep) {
for (Point g : points) {
if (g.x != pp.x || g.y != pp.y) {
if (pp.distance(g) <= range) {
keep = false;
break;
}
}
}
}

if (keep) {
points.add(new Point(x, y));
j += 1;
}

cogX += x;
cogY += y;
p += 1;
}
}
}
}
Expand Down Expand Up @@ -198,5 +220,73 @@ private static int clamp(int c) {
return 255;
}
return c;
}
}


/**
* ArrayList to store the points for a detected motion
*/
ArrayList<Point> points = new ArrayList<Point>();

/**
* The default minimum range between each point where motion has been detected
*/
public static final int DEFAULT_RANGE = 50;

/**
* The default for the max amount of points that can be detected at one time
*/
public static final int DEFAULT_MAX_POINTS = 100;

/**
* The current minimum range between points
*/
private int range = DEFAULT_RANGE;

/**
* The current max amount of points
*/
private int maxPoints = DEFAULT_MAX_POINTS;

/**
* Set the minimum range between each point detected
* @param i the range to set
*/
public void setPointRange(int i){
range = i;
}

/**
* Get the current minimum range between each point
* @return The current range
*/
public int getPointRange(){
return range;
}


/**
* Set the max amount of points that can be detected at one time
* @param i The amount of points that can be detected
*/
public void setMaxPoints(int i){
maxPoints = i;
}


/**
* Get the current max amount of points that can be detected at one time
* @return
*/
public int getMaxPoints(){
return maxPoints;
}

/**
* Returns the currently stored points that have been detected
* @return The current points
*/
public ArrayList<Point> getPoints(){
return points;
}
}
Loading