package developer.image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import javax.imageio.ImageIO;
import oculusPrime.PlayerCommands;
import oculusPrime.commport.ArduinoPrime;
import org.red5.server.api.IConnection;
import org.red5.server.api.service.IServiceCapableConnection;
import oculusPrime.Application;
import oculusPrime.State;
import oculusPrime.Util;
public class motionDetect {
private State state = State.getReference();
private ImageUtils imageUtils = new ImageUtils();
private IConnection grabber = null;
private Application app = null;
private int threshold;
private int[] lastMassCtr=new int[2];
public motionDetect(Application a, IConnection g, int t) {
threshold = t;
this.grabber = g;
this.app = a;
start();
}
private void start() {
state.delete(State.values.streamactivity);
state.set(State.values.motiondetect, true);
new Thread(new Runnable() {
public void run() {
try {
int frameno = 0;
while (state.getBoolean(State.values.motiondetect)) { // TODO: time out after a while
if(state.getBoolean(State.values.framegrabbusy.name()) ||
!(state.get(State.values.stream).equals(Application.streamstate.camera.toString()) ||
state.get(State.values.stream).equals(Application.streamstate.camandmic.toString()))) {
app.message("framegrab busy or stream unavailable", null,null);
state.set(State.values.motiondetect, false);
return;
}
state.set(State.values.framegrabbusy.name(), true);
IServiceCapableConnection sc = (IServiceCapableConnection) grabber;
sc.invoke("framegrabMedium", new Object[] {});
while (state.getBoolean(State.values.framegrabbusy)) {
int n = 0;
Thread.sleep(5);
n++;
if (n> 2000) { // give up after 10 seconds
Util.debug("frame grab timed out", this);
state.set(State.values.framegrabbusy, false);
state.set(State.values.motiondetect, false);
return;
}
}
BufferedImage img = null;
if (Application.framegrabimg != null) {
// convert bytes to image
ByteArrayInputStream in = new ByteArrayInputStream(Application.framegrabimg);
img = ImageIO.read(in);
in.close();
}
else if (Application.processedImage != null) {
img = Application.processedImage;
}
int[] greypxls = imageUtils.convertToGrey(img);
int[] bwpxls = imageUtils.convertToBW(greypxls);
int sensitivity = 4;
int[] ctrxy = imageUtils.middleMass(bwpxls, img.getWidth(), img.getHeight(), sensitivity);
if (frameno >= 1) { // ignore frames 0
int compared = Math.abs(ctrxy[0]-lastMassCtr[0])+Math.abs(ctrxy[1]-lastMassCtr[1]);
if (compared> threshold && state.getBoolean(State.values.motiondetect)) { //motion detected above noise level
// lastMassCtr[0] = -1;
state.set(State.values.motiondetect, false);
if (!state.get(State.values.direction).equals(ArduinoPrime.direction.stop.toString())) {
Util.log("error motion detect attempt while moving", true);
return;
}
state.set(State.values.streamactivity, "video " + compared); // System.currentTimeMillis());
app.driverCallServer(PlayerCommands.messageclients, "motion detected " + compared);
}
}
lastMassCtr = ctrxy;
frameno ++;
}
} catch (Exception e) { e.printStackTrace(); }
}
}).start();
}
}