Skip to content

Commit

Permalink
Updates to the LUMA State based approach
Browse files Browse the repository at this point in the history
git-svn-id: https://android-motion-detection.googlecode.com/svn/trunk@18 996b93ed-3e4d-4b21-1044-74bd19560d1d
  • Loading branch information
[email protected] committed Sep 12, 2011
1 parent 40efdb2 commit d4a09a4
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 158 deletions.
160 changes: 103 additions & 57 deletions src/com/jwetherell/motion_detection/detection/Comparer.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.jwetherell.motion_detection.detection;

import android.util.Log;
import android.graphics.Color;

/**
* This class is adapted from the web site below. It is used to compare two State objects.
Expand All @@ -10,100 +10,126 @@
* @author Justin Wetherell <[email protected]>
*/
public class Comparer {
private static final String TAG = "Comparer";

private int comparex;
private int comparey;
private State state1 = null;
private State state2 = null;
private int xBoxes;
private int yBoxes;
private int xPixelsPerBox;
private int yPixelsPerBox;
private int leniency;
private int debugMode; // 1: textual indication of change, 2: difference of factors

private int[][] variance = null;
private boolean different = false;

public Comparer(int comparex, int comparey, int leniency) {
this.comparex = comparex;
this.comparey = comparey;
public Comparer(State s1, State s2, int xBoxes, int yBoxes, int leniency) {
this.state1 = s1;
this.state2 = s2;

this.xBoxes = xBoxes;
if (xBoxes > state1.getWidth()) xBoxes = state1.getWidth();

this.yBoxes = yBoxes;
if (yBoxes > state1.getHeight()) yBoxes = state1.getHeight();

this.leniency = leniency;
this.debugMode = 0;
}

// want to see some stuff in the console as the comparison is happening?
public void setDebugMode(int m) {
this.debugMode = m;
}

// compare two images.
public Comparison compare(State s1, State s2) {
if (s1==null || s2==null)
throw new NullPointerException();
if (s1.getWidth()!=s2.getWidth() || s1.getHeight()!=s2.getHeight())
throw new IllegalArgumentException();

// number of boxes
int xBoxes = comparex;
if (xBoxes > s1.getWidth()) xBoxes = s1.getWidth();
int yBoxes = comparey;
if (yBoxes > s1.getHeight()) yBoxes = s1.getHeight();

// how many points per box
int xPixelsPerBox = (int)(Math.floor(s1.getWidth() / xBoxes));
this.xPixelsPerBox = (int)(Math.floor(state1.getWidth() / xBoxes));
if (xPixelsPerBox <= 0) xPixelsPerBox = 1;
int yPixelsPerBox = (int)(Math.floor(s1.getHeight() / yBoxes));
this.yPixelsPerBox = (int)(Math.floor(state1.getHeight() / yBoxes));
if (yPixelsPerBox <= 0) yPixelsPerBox = 1;

this.different = isDifferent(state1,state2);
}

// compare two images and populate the variance variable
public boolean isDifferent(State s1, State s2) {
if (s1==null || s2==null)
throw new NullPointerException();
if (s1.getWidth()!=s2.getWidth() || s1.getHeight()!=s2.getHeight())
throw new IllegalArgumentException();

// Boxes
int[][] variance = new int[yBoxes][xBoxes];
this.variance = new int[yBoxes][xBoxes];

// set to a different by default, if a change is found then flag non-match
boolean different = false;
// loop through whole image and compare individual blocks of images
int ty = 0;
int tx = 0;
int b1 = 0;
int b2 = 0;
int diff = 0;
for (int y = 0; y < yBoxes; y++) {
StringBuilder output = new StringBuilder();
if (debugMode > 0) output.append("|");
ty = y*yPixelsPerBox;
for (int x = 0; x < xBoxes; x++) {
tx = x*xPixelsPerBox;
b1 = aggregateMapArea(s1.getMap(), tx, ty, xPixelsPerBox, yPixelsPerBox);
b2 = aggregateMapArea(s2.getMap(), tx, ty, xPixelsPerBox, yPixelsPerBox);
b1 = aggregateMapArea(state1.getMap(), x, y);
b2 = aggregateMapArea(state2.getMap(), x, y);
diff = Math.abs(b1 - b2);
variance[y][x] = diff;
// the difference in a certain region has passed the threshold value
if (diff > leniency) different = true;
if (debugMode == 1) output.append((different ? "X" : " "));
if (debugMode == 2) output.append(diff + (x < xBoxes - 1 ? "," : ""));
}
if (debugMode > 0) {
output.append("|");
Log.d(TAG, output.toString());
}
}
return (new Comparison(s1, s2, variance, different));
return different;
}

private static int aggregateMapArea(int[] map, int ox, int oy, int w, int h) {
private int aggregateMapArea(int[] map, int xBox, int yBox) {
if (map==null) throw new NullPointerException();

int t = 0;
int ty = 0;
int tx = 0;
for (int y = 0; y < h; y++) {
ty = oy+y;
for (int x = 0; x < w; x++) {
tx = ox+x;
t += map[ty+tx];
int i = 0;
int rowOffset = (yBox*yPixelsPerBox)*(yBoxes*yPixelsPerBox);
int columnOffset = (xBox*xPixelsPerBox);
int iy = 0;
for (int y = 0; y < yPixelsPerBox; y++) {
iy = (y*(yBoxes*yPixelsPerBox));
for (int x = 0; x < xPixelsPerBox; x++) {
i += map[rowOffset+columnOffset+iy+x];
}
}

return (i/(xPixelsPerBox*yPixelsPerBox));
}

public void paintDifferences(int[] data) {
if (data==null) throw new NullPointerException();

int diff = 0;
for (int y = 0; y < yBoxes; y++) {
for (int x = 0; x < xBoxes; x++) {
diff = variance[y][x];
if (diff > leniency) paintRed(data, x, y);
}
}
return (t/(w*h));
}

private int paintRed(int[] data, int xBox, int yBox) {
if (data==null) throw new NullPointerException();

int i = 0;
int rowOffset = (yBox*yPixelsPerBox)*(yBoxes*yPixelsPerBox);
int columnOffset = (xBox*xPixelsPerBox);
int iy = 0;
for (int y = 0; y < yPixelsPerBox; y++) {
iy = (y*(yBoxes*yPixelsPerBox));
for (int x = 0; x < xPixelsPerBox; x++) {
data[rowOffset+columnOffset+iy+x] = Color.RED;;
}
}

return (i/(xPixelsPerBox*yPixelsPerBox));
}

// want to see some stuff in the console as the comparison is happening?
public void setDebugMode(int m) {
this.debugMode = m;
}

public int getCompareX() {
return comparex;
return xBoxes;
}

public int getCompareY() {
return comparey;
return yBoxes;
}

public int getLeniency() {
Expand All @@ -113,4 +139,24 @@ public int getLeniency() {
public int getDebugMode() {
return debugMode;
}

public boolean isDifferent() {
return different;
}

@Override
public String toString() {
int diff = 0;
StringBuilder output = new StringBuilder();
for (int y = 0; y < yBoxes; y++) {
output.append('|');
for (int x = 0; x < xBoxes; x++) {
diff = variance[y][x];
if (debugMode == 1) output.append((different ? 'X' : ' '));
if (debugMode == 2) output.append(diff + (x < xBoxes - 1 ? "," : ""));
}
output.append("|\n");
}
return output.toString();
}
}
95 changes: 0 additions & 95 deletions src/com/jwetherell/motion_detection/detection/Comparison.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public abstract class MotionDetection {
//Specific settings
private static final int mPixelThreshold = 50; //Difference in pixel (RGB & LUMA)
private static final int mThreshold = 10000; //Number of different pixels (RGB & LUMA)
private static final int mLeniency = 100; //Difference of aggregate map (State)
private static final int mLeniency = 50; //Difference of aggregate map (State)
private static final int mDebugMode = 2; //State based debug (State)

private static int[] mPrevious = null;
Expand All @@ -31,23 +31,23 @@ public static int[] getPrevious() {

protected static boolean isDifferentComparingState(int[] first, int width, int height) {
if (first==null) throw new NullPointerException();

if (mPrevious==null) return false;
if (first.length != mPrevious.length) return true;
if (mPreviousWidth != width || mPreviousHeight != height) return true;

if (mPreviousState==null) mPreviousState = new State(mPrevious, mPreviousWidth, mPreviousHeight);
State state = new State(first, width, height);

Comparer ic = new Comparer((width/50), (height/50), mLeniency);
Comparer ic = new Comparer(state,mPreviousState,(width/50), (height/50), mLeniency);
ic.setDebugMode(mDebugMode);
Comparison c = ic.compare(state,mPreviousState);
System.out.println(ic.toString());

boolean different = c.isDifferent();
boolean different = ic.isDifferent();
String output = "isDifferent="+different;
if (different) {
Log.e(TAG, output);
c.getChangeIndicator(first, width, height, ic);
ic.paintDifferences(first);
} else {
Log.d(TAG, output);
}
Expand Down

0 comments on commit d4a09a4

Please sign in to comment.