package com.mikeefranklin.birdcam; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.graphics.Matrix; import android.graphics.YuvImage; import android.util.Log; public class Detector { byte[] previous_frame; public Detector() { } public boolean detect(byte[] data, int width, int height) { for (int y = 0, i = 0; y < height; y++) { for (int x = 0; x < width; x++, i++) { int l = (0xff & ((int) data[i])) - 16; // if theres a previous frame, lets do a diff on it if (previous_frame != null) { int pl = (0xff & ((int) previous_frame[i])) - 16; int d = pl; d = ((int)(((0.7 * l) + (0.3 * d)))-d); if (d < 0){ d = -d; } if (d > 50) { previous_frame = data; return true; } }else { } } } previous_frame = data; return false; } }
fastdetect : function(that){ var half_height = this.pixels.height / 2; var half_width = this.pixels.width / 2; for(var y=0; y<half_height; y++){ for(var x=0; x<half_width; x++){ var i = (y * 8) * this.pixels.width + x * 8; var r = this.pixels.data[i]; var g = this.pixels.data[i+1]; var b = this.pixels.data[i+2]; var tr = that.pixels.data[i]; var tg = that.pixels.data[i+1]; var tb = that.pixels.data[i+2]; var yuv = rgb_to_yuv(r, g, b); var yuv2 = rgb_to_yuv(tr, tg, tb); var this_col = yuv[0]; var that_col = yuv2[0]; this_col = (((5 * this_col) + (5 * that_col))/10)-that_col; if (this_col < 0) this_col = -this_col; this_col = this_col > 15 ? 255 : 0; this.pixels.data[i] = this_col; this.pixels.data[i+1] = this_col; this.pixels.data[i+2] = this_col; } } var mask = []; for(var y=0; y<half_height; y++){ for(var x=0; x<half_width; x++){ var i = (y * 8) * this.pixels.width + x * 8; var erode = false; if (this.pixels.data[i] == 255){ for (var yi=-2;yi<=2;yi+=2){ for (var xi=-2;xi<=2;xi+=2){ var px = ((y+yi) * 8) * this.pixels.width + (x+xi) * 8; if (this.pixels.data[px] == 0){ erode = true; break; } } } mask.push({'i' : i, 'erode' : erode ? 0 : 255}); }else { mask.push({'i' : i, 'erode' : 0}); } } } for (var i=0; i<mask.length; i++){ this.pixels.data[mask[i].i] = mask[i].erode; this.pixels.data[mask[i].i+1] = mask[i].erode; this.pixels.data[mask[i].i+2] = mask[i].erode; } return false; }
public boolean detect(byte[] data, int width, int height) { // half width and height to reduce loops int half_height = height / 2; int half_width = width / 2; // boolean map to hold our threshold pic boolean[] map = new boolean[half_height * half_width]; for (int y = 0, i = 0, ii = 0; y < half_height; y++) { for (int x = 0; x < half_width; x++, i+=2,ii++) { int l = (0xff & ((int) data[i])) - 16; if (previous_frame != null) { int pl = (0xff & ((int) previous_frame[i])) - 16; int d = pl; // merge 50% of each frame, lets not use division d = ((int)((5 * l) + (5 * d))-(d*10)); // if theres a negative diff, lets reverse it if (d < 0){ d = -d; } //build up our threshold map map[ii] = d > 150; } } } previous_frame = data; boolean erode = false; for (int y = 0, i = 0; y < half_height; y++) { for (int x = 0; x < half_width; x++, i++) { erode = false; if (map[i]) { loop through the pixels around it for (int yi=-2;yi<=2;yi++){ for (int xi=-2;xi<=2;xi++){ int px = (y+yi) * half_width + (x+xi); if (px >= 0 && px < map.length) { // if a pixel is eroded, carry on if (!map[px]) { erode = true; break; } } } } // if no pixels around this pixel have been eroded, we know there's probably some motion if (!erode) { return true; } } } } return false; }