Skip to content

Commit

Permalink
re-use the MotionDetector, and other improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
n8fr8 committed Jul 6, 2018
1 parent 625cab5 commit 7070dbb
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 98 deletions.
168 changes: 102 additions & 66 deletions src/main/java/org/havenapp/main/sensors/motion/CameraViewHolder.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@

package org.havenapp.main.sensors.motion;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
Expand All @@ -22,6 +24,7 @@
import android.os.RemoteException;
import android.support.v8.renderscript.RenderScript;
import android.util.Log;
import android.view.Surface;

import com.google.android.cameraview.CameraView;

Expand Down Expand Up @@ -88,7 +91,7 @@ public class CameraViewHolder {
private CameraView cameraView = null;
private Messenger serviceMessenger = null;
//private Camera camera;
private Context context;
private Activity context;
private MotionDetector task;

AndroidSequenceEncoder encoder;
Expand All @@ -112,7 +115,7 @@ public void onServiceDisconnected(ComponentName arg0) {
}
};

public CameraViewHolder(Context context, CameraView cameraView) {
public CameraViewHolder(Activity context, CameraView cameraView) {
//super(context);
this.context = context;
this.cameraView = cameraView;
Expand All @@ -122,8 +125,60 @@ public CameraViewHolder(Context context, CameraView cameraView) {

motionSensitivity = prefs.getCameraSensitivity();

initCamera();

task = new MotionDetector(
renderScript,
updateHandler,
motionSensitivity);

task.addListener((sourceImage, detectedImage, rawBitmap, motionDetected) -> {

if (motionDetected) {
Log.i("MotionListener", "Motion detected");

for (MotionDetector.MotionListener listener : listeners)
listener.onProcess(sourceImage,detectedImage,rawBitmap,motionDetected);

if (serviceMessenger != null) {
Message message = new Message();
message.what = EventTrigger.CAMERA;

try {

File fileImageDir = new File(Environment.getExternalStorageDirectory(), prefs.getImagePath());
fileImageDir.mkdirs();

String ts = new Date().getTime() + ".jpg";

File fileImage = new File(fileImageDir, "detected.original." + ts);
FileOutputStream stream = new FileOutputStream(fileImage);
rawBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);

stream.flush();
stream.close();
message.getData().putString("path", fileImage.getAbsolutePath());

// sourceImage.recycle();
// detectedImage.recycle();

//store the still match frame, even if doing video
serviceMessenger.send(message);

if (prefs.getVideoMonitoringActive() && (!doingVideoProcessing)) {
recordVideo();

}

} catch (Exception e) {
// Cannot happen
Log.e("CameraViewHolder", "error creating image", e);
}
}
}

Log.i("MotionListener", "Allowing further processing");

});
/*
* We bind to the alert service
*/
Expand All @@ -149,7 +204,7 @@ public void addListener(MotionDetector.MotionListener listener) {
* (preferred is 640x480)
* in order to minimize CPU usage
*/
public void initCamera() {
public void startCamera() {


switch (prefs.getCamera()) {
Expand Down Expand Up @@ -192,7 +247,7 @@ public void initCamera() {
private final BlockingQueue<Runnable> mDecodeWorkQueue = new LinkedBlockingQueue<Runnable>();

// Creates a thread pool manager
ThreadPoolExecutor mDecodeThreadPool = new ThreadPoolExecutor(
private ThreadPoolExecutor mDecodeThreadPool = new ThreadPoolExecutor(
1, // Initial pool size
1, // Max pool size
10,
Expand All @@ -203,12 +258,12 @@ public void initCamera() {
private final BlockingQueue<Runnable> mEncodeVideoWorkQueue = new LinkedBlockingQueue<Runnable>();

// Creates a thread pool manager
ThreadPoolExecutor mEncodeVideoThreadPool = new ThreadPoolExecutor(
private ThreadPoolExecutor mEncodeVideoThreadPool = new ThreadPoolExecutor(
1, // Initial pool size
1, // Max pool size
10,
TimeUnit.SECONDS,
mDecodeWorkQueue);
mEncodeVideoWorkQueue);


private void recordNewFrame (byte[] data, int width, int height, int rotationDegrees)
Expand Down Expand Up @@ -243,71 +298,16 @@ private void recordNewFrame (byte[] data, int width, int height, int rotationDeg
}
}

private void processNewFrame (byte[] data, int width, int height, int rotationDegrees)
private synchronized void processNewFrame (byte[] data, int width, int height, int rotationDegrees)
{


task = new MotionDetector(
renderScript,
task.detect(
lastPic,
data,
width,
height,
rotationDegrees,
cameraView.getFacing(),
updateHandler,
motionSensitivity);

task.addListener((sourceImage, detectedImage, rawBitmap, motionDetected) -> {

if (motionDetected) {
Log.i("MotionListener", "Motion detected");

for (MotionDetector.MotionListener listener : listeners)
listener.onProcess(sourceImage,detectedImage,rawBitmap,motionDetected);

if (serviceMessenger != null) {
Message message = new Message();
message.what = EventTrigger.CAMERA;

try {

File fileImageDir = new File(Environment.getExternalStorageDirectory(), prefs.getImagePath());
fileImageDir.mkdirs();

String ts = new Date().getTime() + ".jpg";

File fileImage = new File(fileImageDir, "detected.original." + ts);
FileOutputStream stream = new FileOutputStream(fileImage);
rawBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);

stream.flush();
stream.close();
message.getData().putString("path", fileImage.getAbsolutePath());

// sourceImage.recycle();
// detectedImage.recycle();

//store the still match frame, even if doing video
serviceMessenger.send(message);

if (prefs.getVideoMonitoringActive() && (!doingVideoProcessing)) {
recordVideo();
cameraView.getDefaultOrientation(),
cameraView.getFacing());

}

} catch (Exception e) {
// Cannot happen
Log.e("CameraViewHolder", "error creating image", e);
}
}
}

Log.i("MotionListener", "Allowing further processing");

});

task.detect();
lastPic = data;

}
Expand Down Expand Up @@ -356,4 +356,40 @@ public void destroy ()
}
stopCamera();
}

public int getCorrectCameraOrientation(int facing, int orientation) {

int rotation = context.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;

switch(rotation){
case Surface.ROTATION_0:
degrees = 0;
break;

case Surface.ROTATION_90:
degrees = 90;
break;

case Surface.ROTATION_180:
degrees = 180;
break;

case Surface.ROTATION_270:
degrees = 270;
break;

}

int result;
if(facing == CameraView.FACING_FRONT){
result = (orientation + degrees) % 360;
result = (360 - result) % 360;
}else{
result = (orientation - degrees + 360) % 360;
}

return result;
}

}
42 changes: 18 additions & 24 deletions src/main/java/org/havenapp/main/sensors/motion/MotionDetector.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,8 @@ public class MotionDetector {
// Input data

private List<MotionListener> listeners = new ArrayList<>();
private byte[] rawOldPic;
private byte[] rawNewPic;
private int width;
private int height;
private Handler handler;
private int motionSensitivity;
private int rotationDegrees;
private int cameraFacing;
// Output data

private boolean hasChanged;
Expand All @@ -58,6 +52,7 @@ public class MotionDetector {

private RenderScript renderScript;

private int detectColor = Color.YELLOW;

public interface MotionListener {
public void onProcess(Bitmap oldBitmap,
Expand All @@ -72,34 +67,33 @@ public void addListener(MotionListener listener) {

public MotionDetector(
RenderScript renderScript,
byte[] rawOldPic,
byte[] rawNewPic,
int width,
int height,
int rotationDegrees,
int cameraFacing,
Handler updateHandler,
int motionSensitivity) {
this.renderScript = renderScript;
this.rawOldPic = rawOldPic;
this.rawNewPic = rawNewPic;
this.width = width;
this.height = height;
this.rotationDegrees = rotationDegrees;
this.cameraFacing = cameraFacing;
this.handler = updateHandler;
this.motionSensitivity = motionSensitivity;
detector = new LuminanceMotionDetector();

}

public void setDetectColor (int detectColor)
{
this.detectColor = detectColor;
}

public void setMotionSensitivity (int motionSensitivity)
{
this.motionSensitivity = motionSensitivity;
detector.setThreshold(motionSensitivity);
}

public void detect() {
public void detect(byte[] rawOldPic,
byte[] rawNewPic,
int width,
int height,
int rotationDegrees,
int cameraFacing) {

int[] newPicLuma = ImageCodec.N21toLuma(rawNewPic, width, height);
if (rawOldPic != null) {

Expand All @@ -126,18 +120,18 @@ public void detect() {
newPic[i] = Color.TRANSPARENT;

for (int changedPixel : changedPixels) {
newPic[changedPixel] = Color.YELLOW;
newPic[changedPixel] = detectColor;
}


Matrix mtx = new Matrix();

if (cameraFacing == CameraView.FACING_FRONT) {
mtx.postRotate(-90);
mtx.postRotate(-rotationDegrees);
mtx.postScale(-1, 1, width / 2, height / 2);
}
else
mtx.postRotate(90);
}
else
mtx.postRotate(rotationDegrees);


Bitmap newBitmap
Expand Down
21 changes: 13 additions & 8 deletions src/main/java/org/havenapp/main/ui/CameraFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ public void stopCamera ()
{
if (cameraViewHolder != null) {
cameraViewHolder.stopCamera();
cameraViewHolder = null;
}
}

Expand All @@ -76,29 +75,35 @@ public void resetCamera ()
private void initCamera ()
{

newImage = getActivity().findViewById(R.id.new_image);

PreferenceManager prefs = new PreferenceManager(getActivity());

if (prefs.getCameraActivation()) {
//Uncomment to see the camera

CameraView cameraView = getActivity().findViewById(R.id.camera_view);

cameraViewHolder = new CameraViewHolder(getContext().getApplicationContext(),cameraView);
if (cameraViewHolder == null) {
cameraViewHolder = new CameraViewHolder(getActivity(), cameraView);

newImage = getActivity().findViewById(R.id.new_image);
cameraViewHolder.addListener((oldBitmap, newBitmap, rawBitmap, motionDetected) -> {
if (motionDetected)
newImage.setImageBitmap(newBitmap);
});
}

cameraViewHolder.addListener((oldBitmap, newBitmap, rawBitmap, motionDetected) -> {
if (motionDetected)
newImage.setImageBitmap(newBitmap);
});
cameraViewHolder.startCamera();
}

}

@Override
public void onDestroy() {
super.onDestroy();
cameraViewHolder.destroy();

if (cameraViewHolder != null)
cameraViewHolder.destroy();

}

Expand Down

0 comments on commit 7070dbb

Please sign in to comment.