java - How to do Android Motion Detection For Specific Area -
trying make motion detection app based on this project. intention make app take pictures when motion detected comparing 2 images. part, app working fine.
requirement:
to specify area of detection custom view. that, pictures captured if motion detected inside defined area calculating detection area.
what have done far:
created movable custom view, crop view of dimensions (rect
) saved in preference each time when view moved.
what not working:
the motion detection inside custom view not working. believe bitmaps must cropped according size of custom view comparison. in detection thread tried setting width
, height
preference : private int width = prefe.detectionarea.width(); private int height = prefe.detectionarea.height();
but didn't work. please me explaining how achieved motion detection happen according size of custom view. appreciated.
project source code: https://drive.google.com/drive/folders/0b7-okqt7w49mbtr6vwzyvurmvms
motiondetectionactivity.java
public class motiondetectionactivity extends sensorsactivity { private static final string tag = "motiondetectionactivity"; private static long mreferencetime = 0; private static imotiondetection detector = null; public static mediaplayer song; public static vibrator mvibrator; private static surfaceview preview = null; private static surfaceholder previewholder = null; private static camera camera = null; private static boolean inpreview = false; private static areadetectorview mdetector; private static framelayout layoutdetectorarea; static framelayout layoutmain; static view mview; private static volatile atomicboolean processing = new atomicboolean(false); /** * {@inheritdoc} */ @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); getwindow().addflags(windowmanager.layoutparams.flag_keep_screen_on); setcontentview(r.layout.main); mvibrator = (vibrator)this.getsystemservice(vibrator_service); layoutmain=(framelayout)findviewbyid(r.id.layoutmain); preview = (surfaceview) findviewbyid(r.id.preview); previewholder = preview.getholder(); previewholder.addcallback(surfacecallback); previewholder.settype(surfaceholder.surface_type_push_buffers); mview=layoutmain; mdetector= (areadetectorview) findviewbyid(r.id.viewdetector); layoutdetectorarea=(framelayout) findviewbyid(r.id.layoutdetectarea); togglebutton toggle = (togglebutton) findviewbyid(r.id.simpletogglebutton); toggle.setoncheckedchangelistener(new compoundbutton.oncheckedchangelistener() { public void oncheckedchanged(compoundbutton buttonview, boolean ischecked) { if (ischecked) { // toggle enabled } else { // toggle disabled } } }); if (preferences.use_rgb) { detector = new rgbmotiondetection(); } else if (preferences.use_luma) { detector = new lumamotiondetection(); } else { // using state based (aggregate map) detector = new aggregatelumamotiondetection(); } } /** * {@inheritdoc} */ @override public void onconfigurationchanged(configuration newconfig) { super.onconfigurationchanged(newconfig); } /**dd: * song play # 1 * camera callback * * {@inheritdoc} */ @override public void onpause() { super.onpause(); if(song!=null && song.isplaying()) { song.stop();} camera.setpreviewcallback(null); if (inpreview) camera.stoppreview(); inpreview = false; camera.release(); camera = null; } /** * {@inheritdoc} */ @override public void onresume() { super.onresume(); camera = camera.open(); } private previewcallback previewcallback = new previewcallback() { /** * {@inheritdoc} */ @override public void onpreviewframe(byte[] data, camera cam) { if (data == null) return; camera.size size = cam.getparameters().getpreviewsize(); if (size == null) return; if (!globaldata.isphoneinmotion()) { detectionthread thread = new detectionthread(data, size.width, size.height); thread.start(); } } }; private surfaceholder.callback surfacecallback = new surfaceholder.callback() { /** * {@inheritdoc} */ @override public void surfacecreated(surfaceholder holder) { try { camera.setpreviewdisplay(previewholder); camera.setpreviewcallback(previewcallback); } catch (throwable t) { log.e("prek", "exception in setpreviewdisplay()", t); } } /** * {@inheritdoc} */ @override public void surfacechanged(surfaceholder holder, int format, int width, int height) { if(camera != null) { camera.parameters parameters = camera.getparameters(); parameters.setfocusmode(camera.parameters.focus_mode_continuous_picture); camera.size size = getbestpreviewsize(width, height, parameters); if (size != null) { parameters.setpreviewsize(size.width, size.height); log.d(tag, "using width=" + size.width + " height=" + size.height); } camera.setparameters(parameters); camera.startpreview(); inpreview = true; } //areadetectorview.initdetectionarea(); } /** * {@inheritdoc} */ @override public void surfacedestroyed(surfaceholder holder) { // ignore } }; private static camera.size getbestpreviewsize(int width, int height, camera.parameters parameters) { camera.size result = null; (camera.size size : parameters.getsupportedpreviewsizes()) { if (size.width <= width && size.height <= height) { if (result == null) { result = size; } else { int resultarea = result.width * result.height; int newarea = size.width * size.height; if (newarea > resultarea) result = size; } } } return result; } //***************detection class******************// private final class detectionthread extends thread { private byte[] data; private int width; private int height; public detectionthread(byte[] data, int width, int height) { this.data = data; this.width = width; this.height = height; } /** * {@inheritdoc} */ @override public void run() { if (!processing.compareandset(false, true)) return; // log.d(tag, "begin processing..."); try { // previous frame int[] pre = null; if (preferences.save_previous) pre = detector.getprevious(); // current frame (with changes) // long bconversion = system.currenttimemillis(); int[] img = null; if (preferences.use_rgb) { img = imageprocessing.decodeyuv420sptorgb(data, width, height); } else { img = imageprocessing.decodeyuv420sptoluma(data, width, height); } // current frame (without changes) int[] org = null; if (preferences.save_original && img != null) org = img.clone(); if (img != null && detector.detect(img, width, height)) { // delay necessary avoid taking picture while in // // middle of taking another. problem can causes // phones // reboot. long = system.currenttimemillis(); if (now > (mreferencetime + preferences.picture_delay)) { mreferencetime = now; //mvibrator.vibrate(10); bitmap previous = null; if (preferences.save_previous && pre != null) { if (preferences.use_rgb) previous = imageprocessing.rgbtobitmap(pre, width, height); else previous = imageprocessing.lumatogreyscale(pre, width, height); } bitmap original = null; if (preferences.save_original && org != null) { if (preferences.use_rgb) original = imageprocessing.rgbtobitmap(org, width, height); else original = imageprocessing.lumatogreyscale(org, width, height); } bitmap bitmap = null; if (preferences.save_changes) { if (preferences.use_rgb) bitmap = imageprocessing.rgbtobitmap(img, width, height); else bitmap = imageprocessing.lumatogreyscale(img, width, height); } log.i(tag, "saving.. previous=" + previous + " original=" + original + " bitmap=" + bitmap); looper.prepare(); new savephototask().execute(previous, original, bitmap); } else { log.i(tag, "not taking picture because not enough time has passed since creation of surface"); } } } catch (exception e) { e.printstacktrace(); } { processing.set(false); } // log.d(tag, "end processing..."); processing.set(false); } }; private static final class savephototask extends asynctask<bitmap, integer, integer> { /** * {@inheritdoc} */ @override protected integer doinbackground(bitmap... data) { (int = 0; < data.length; i++) { bitmap bitmap = data[i]; string name = string.valueof(system.currenttimemillis()); if (bitmap != null) save(name, bitmap); } return 1; } private void save(string name, bitmap bitmap) { file photo = new file(environment.getexternalstoragedirectory(), name + ".jpg"); if (photo.exists()) photo.delete(); try { fileoutputstream fos = new fileoutputstream(photo.getpath()); bitmap.compress(bitmap.compressformat.jpeg, 100, fos); fos.close(); } catch (java.io.ioexception e) { log.e("picturedemo", "exception in photocallback", e); } } } }
areadetectorview.java
public class areadetectorview extends linearlayout { public static int width; public static int height; private static paint boxpaint = null; private static paint textpaint = null; private static paint arrowpaint = null; private static path mpath = null; private static rect mrect = null; private static int lastx, lasty = 0; private static boolean mboxtouched = false; private static boolean marrowtouched = false; private static context mcontext; private static int arrowwidth = 0; private static paint boxpaint2 = null; public areadetectorview(context context) { super(context); mcontext = context; } //attrs not there public areadetectorview(context context, attributeset attrs) { super(context,attrs); mcontext = context; // todo auto-generated constructor stub if (!this.getrootview().isineditmode()) { arrowwidth =getdisplaypixel(context, 30); } //initdetectionarea(); initmembervariables(); setwillnotdraw(false); } public static int getdisplaypixel(context paramcontext, int paramint) { return (int)(paramint * paramcontext.getresources().getdisplaymetrics().density + 0.5f); } public static void initmembervariables() { if (boxpaint == null) { boxpaint = new paint(); boxpaint.setantialias(true); boxpaint.setstrokewidth(2.0f); //boxpaint.setstyle(style.stroke); boxpaint.setstyle(style.fill_and_stroke); boxpaint.setcolor(contextcompat.getcolor(mcontext, r.color.bwff_60)); } if (arrowpaint == null) { arrowpaint = new paint(); arrowpaint.setantialias(true); arrowpaint.setcolor(contextcompat.getcolor(mcontext,r.color.reddd)); arrowpaint.setstyle(style.fill_and_stroke); } if (textpaint == null) { textpaint = new paint(); textpaint.setcolor(contextcompat.getcolor(mcontext,r.color.yellowl)); textpaint.settextsize(16); //txtpaint.settypeface(lcd); textpaint.setstyle(style.fill_and_stroke); } if (mpath == null) { mpath = new path(); } else { mpath.reset(); } if (mrect == null) { mrect = new rect(); } if (boxpaint2 == null) { boxpaint2 = new paint(); boxpaint2.setantialias(true); boxpaint2.setstrokewidth(2.0f); //boxpaint.setstyle(style.stroke); boxpaint2.setstyle(style.stroke); boxpaint2.setcolor(contextcompat.getcolor(mcontext,r.color.bwff_9e)); } } public static void initdetectionarea() { try { int w = prefe.detectionarea.width(); int h = prefe.detectionarea.height(); int x = prefe.detectionarea.left; int y = prefe.detectionarea.top; // ver 2.6.0 if (prefe.detectionarea.left == 1 && prefe.detectionarea.top == 1 && prefe.detectionarea.right == 1 && prefe.detectionarea.bottom == 1) { w = prefe.displaywidth / 4; h = prefe.displayheight / 3; // ver 2.5.9 w = width / 4; h = height / 3; prefe.detectorwidth = w; //utilgeneralhelper.getdisplaypixel(this, 100); prefe.detectorheight = h; //utilgeneralhelper.getdisplaypixel(this, 100); x = (prefe.displaywidth / 2) - (w / 2); y = (prefe.displayheight / 2) - (h / 2); // ver 2.5.9 x = (width / 2) - (w / 2); y = (height / 2) - (h / 2); } //prefe.detectionarea = new rect(x, x, x + prefe.detectorwidth, x + prefe.detectorheight); prefe.detectionarea = new rect(x, y, x + w, y + h); prefe.gdetectionbitmapint = new int[prefe.detectionarea.width() * prefe.detectionarea.height()]; prefe.gdetectionbitmapintprev = new int[prefe.detectionarea.width() * prefe.detectionarea.height()]; } catch (exception e) { e.printstacktrace(); } } public static void setdetectionarea(int x, int y, int w, int h) { try { prefe.detectionarea = new rect(x, y, w, h); } catch (exception e) { e.printstacktrace(); } } private void drawareabox(canvas canvas) { try { } catch (exception e) { e.printstacktrace(); } } @override protected void dispatchdraw(canvas canvas) { try { if (this.getrootview().isineditmode()) { super.dispatchdraw(canvas); return; } //canvas.save(canvas.matrix_save_flag); //prefe.detectionareaorient = utilgeneralhelper.getdetectrectbyorientation(); canvas.drawcolor(0); mpath.reset(); canvas.drawrect(prefe.detectionarea, boxpaint); mpath.moveto(prefe.detectionarea.right - arrowwidth, prefe.detectionarea.bottom); mpath.lineto(prefe.detectionarea.right, prefe.detectionarea.bottom - arrowwidth); mpath.lineto(prefe.detectionarea.right, prefe.detectionarea.bottom); mpath.lineto(prefe.detectionarea.right - arrowwidth, prefe.detectionarea.bottom); mpath.close(); canvas.drawpath(mpath, arrowpaint); mpath.reset(); //canvas.drawrect(prefe.detectionareaorient, boxpaint2); //canvas.drawrect(prefe.detectionareaorientport, boxpaint2); textpaint.settextsize(16); //textpaint.setletterspacing(2); textpaint.setcolor(contextcompat.getcolor(mcontext,r.color.bwff)); textpaint.gettextbounds(getresources().getstring(r.string.str_detectarea), 0, 1, mrect); canvas.drawtext(getresources().getstring(r.string.str_detectarea), prefe.detectionarea.left + 4, prefe.detectionarea.top + 4 + mrect.height(), textpaint); int rech = mrect.height(); textpaint.setstrokewidth(1.2f); textpaint.settextsize(18); textpaint.setcolor(contextcompat.getcolor(mcontext,r.color.redd_9e)); textpaint.gettextbounds(getresources().getstring(r.string.str_dragandmove), 0, 1, mrect); canvas.drawtext(getresources().getstring(r.string.str_dragandmove), prefe.detectionarea.left + 4, prefe.detectionarea.top + 20 + mrect.height()*2, textpaint); textpaint.gettextbounds(getresources().getstring(r.string.str_scalearea), 0, 1, mrect); canvas.drawtext(getresources().getstring(r.string.str_scalearea), prefe.detectionarea.left + 4, prefe.detectionarea.top + 36 + mrect.height()*3, textpaint); super.dispatchdraw(canvas); //canvas.restore(); } catch (exception e) { e.printstacktrace(); } } @override protected void ondraw(canvas canvas) { try { super.ondraw(canvas); invalidate(); } catch (exception e) { e.printstacktrace(); } { } } @override public boolean ontouchevent(motionevent event) { boolean retvalue = true; int x = (int)event.getx(); int y = (int)event.gety(); //appmain.txtloc.settext(string.valueof(x) + ", " + string.valueof(y)); switch (event.getaction()) { case motionevent.action_down: mboxtouched = touchedinboxarea(x, y); //appmain.txtloc.settext("boxtouched: " + string.valueof(mboxtouched)); if (!mboxtouched) break; lastx = x; lasty = y; boxpaint.setstyle(style.fill_and_stroke); boxpaint.setcolor(contextcompat.getcolor(mcontext,r.color.redd_9e)); marrowtouched = touchedinarrow(x, y); //appmain.txtloc.settext("arrowtouched: " + string.valueof(mboxtouched)); if (marrowtouched) { arrowpaint.setcolor(contextcompat.getcolor(mcontext,r.color.bwff_9e)); } break; case motionevent.action_move: if (!mboxtouched) break; int movex = x - lastx; int movey = y - lasty; //appmain.txtloc.settext("move x, y: " + string.valueof(movex) + "," + string.valueof(movey)); if (!marrowtouched) { if (prefe.detectionarea.left + movex < 0) { break; } // if (prefe.detectionarea.right + movex > prefe.gdisplay.getwidth()) { // break; // } // ver 2.5.9 if (prefe.detectionarea.right + movex > width) { break; } if (prefe.detectionarea.top + movey < 0) { break; } // if (prefe.detectionarea.bottom + movey > prefe.gdisplay.getheight()) { // break; // } // ver 2.5.9 if (prefe.detectionarea.bottom + movey > height) { break; } } if (marrowtouched) { if ((prefe.detectionarea.width() + movex) < arrowwidth * 2){ break; } if ((prefe.detectionarea.height() + movey) < arrowwidth * 2) { break; } prefe.detectionarea.right += movex; prefe.detectionarea.bottom += movey; //log.i("dbg", "w,h: " + string.valueof(prefe.detectionarea.width()) + "," + string.valueof(prefe.detectionarea.height())); } else { prefe.detectionarea.left += movex; prefe.detectionarea.right += movex; prefe.detectionarea.top += movey; prefe.detectionarea.bottom += movey; } lastx = x; lasty = y; //appmain.txtloc.settext(string.valueof(prefe.detectionarea.left) + ", " + string.valueof(prefe.detectionarea.top)); break; case motionevent.action_up: mboxtouched = false; marrowtouched = false; //boxpaint.setstyle(style.stroke); boxpaint.setstyle(style.fill_and_stroke); boxpaint.setcolor(contextcompat.getcolor(mcontext,r.color.bwff_60)); arrowpaint.setcolor(contextcompat.getcolor(mcontext,r.color.reddd)); //appmain.txtloc.settext(string.valueof(prefe.detectionarea.left) + ", " + string.valueof(prefe.detectionarea.top)); if (prefe.detectionarea.left < 0) { prefe.detectionarea.left = 0; } // if (prefe.detectionarea.right > prefe.gdisplay.getwidth()) { // prefe.detectionarea.right = prefe.gdisplay.getwidth(); // } // ver 2.5.9 if (prefe.detectionarea.right > width) { prefe.detectionarea.right = width; } if (prefe.detectionarea.top < 0) { prefe.detectionarea.top = 0; } // if (prefe.detectionarea.bottom > prefe.gdisplay.getheight()) { // prefe.detectionarea.bottom = prefe.gdisplay.getheight(); // } if (prefe.detectionarea.bottom > height) { prefe.detectionarea.bottom = height; } prefe.gdetectionbitmapint = new int[prefe.detectionarea.width() * prefe.detectionarea.height()]; prefe.gdetectionbitmapintprev = new int[prefe.detectionarea.width() * prefe.detectionarea.height()]; //prefe.gdetectionbitmapint = null; //prefe.gdetectionbitmapintprev = null; string area = string.valueof(prefe.detectionarea.left) + "," + string.valueof(prefe.detectionarea.top) + "," + string.valueof(prefe.detectionarea.right) + "," + string.valueof(prefe.detectionarea.bottom); // utilgeneralhelper.savepreferencesetting(prefe.gcontext, prefe.pref_detection_area_key, area); //saving value sharedprefsutils.setstringpreference(mcontext.getapplicationcontext(), prefe.pref_detection_area_key, area); log.v("tag", sharedprefsutils.getstringpreference(mcontext.getapplicationcontext(),prefe.pref_detection_area_key)); break; } invalidate(); return retvalue; } private boolean touchedinboxarea(int x, int y) { boolean retvalue = false; try { if (x > prefe.detectionarea.left && x < prefe.detectionarea.right) { if (y > prefe.detectionarea.top && y < prefe.detectionarea.bottom) { retvalue = true; } } } catch (exception e) { e.printstacktrace(); } return retvalue; } private boolean touchedinarrow(int x, int y) { boolean retvalue = false; try { if (x > prefe.detectionarea.right - arrowwidth && x < prefe.detectionarea.right) { if (y > prefe.detectionarea.bottom - arrowwidth && y < prefe.detectionarea.bottom) { retvalue = true; } } } catch (exception e) { e.printstacktrace(); } return retvalue; } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { super.onmeasure(widthmeasurespec, heightmeasurespec); int width = measurespec.getsize(widthmeasurespec); int height = measurespec.getsize(heightmeasurespec); setmeasureddimension(width, height); width = width; height = height; initdetectionarea(); } @override protected void onfinishinflate() { super.onfinishinflate(); } @override protected void onlayout(boolean changed, int l, int t, int r, int b) { // todo auto-generated method stub (int = 0; < this.getchildcount()-1; i++){ (this.getchildat(i)).layout(l, t, r, b); } if (changed) { // check width height if (r != width || b != height) { // size not match } } } }
prefe.java
public class prefe extends application{ ... public static final string pref_detection_area_key = "pref_detection_area_key"; } static{ ... detectionarea = new rect(1, 1, 1, 1); } }
Comments
Post a Comment