diff --git a/app/src/main/java/com/example/greenwatch/VideodetectionAndAccelerometerActivity.java b/app/src/main/java/com/example/greenwatch/VideodetectionAndAccelerometerActivity.java index f6118dd..3cbdfa5 100644 --- a/app/src/main/java/com/example/greenwatch/VideodetectionAndAccelerometerActivity.java +++ b/app/src/main/java/com/example/greenwatch/VideodetectionAndAccelerometerActivity.java @@ -101,12 +101,19 @@ public class VideodetectionAndAccelerometerActivity extends AppCompatActivity im @Override public void onChanged(Boolean aBoolean) { if (aBoolean) { - mVideodetectionAndAccelerometerViewModel.updateDevice(mVideodetectionAndAccelerometerViewModel.getLocalDeviceUUID(), mVideodetectionAndAccelerometerViewModel.getSystemTimeStamp(), true, "Accelerometer", 10); + if (mVideodetectionAndAccelerometerViewModel.getAccelerometerAlarmDetected() && !mVideodetectionAndAccelerometerViewModel.getVideoAlarmDetected()) { + mVideodetectionAndAccelerometerViewModel.updateDevice(mVideodetectionAndAccelerometerViewModel.getLocalDeviceUUID(), mVideodetectionAndAccelerometerViewModel.getSystemTimeStamp(), true, "Accelerometer", 10); + } + else if (mVideodetectionAndAccelerometerViewModel.getVideoAlarmDetected() && !mVideodetectionAndAccelerometerViewModel.getAccelerometerAlarmDetected()) { + mVideodetectionAndAccelerometerViewModel.updateDevice(mVideodetectionAndAccelerometerViewModel.getLocalDeviceUUID(), mVideodetectionAndAccelerometerViewModel.getSystemTimeStamp(), true, "Video", 10); + } + else if (mVideodetectionAndAccelerometerViewModel.getAccelerometerAlarmDetected() && mVideodetectionAndAccelerometerViewModel.getVideoAlarmDetected()) { + mVideodetectionAndAccelerometerViewModel.updateDevice(mVideodetectionAndAccelerometerViewModel.getLocalDeviceUUID(), mVideodetectionAndAccelerometerViewModel.getSystemTimeStamp(), true, "2VideoAndAccelerometer", 10); + } } else { - mVideodetectionAndAccelerometerViewModel.updateDevice(mVideodetectionAndAccelerometerViewModel.getLocalDeviceUUID(), mVideodetectionAndAccelerometerViewModel.getSystemTimeStamp(), false, "Accelerometer", 0); + mVideodetectionAndAccelerometerViewModel.updateDevice(mVideodetectionAndAccelerometerViewModel.getLocalDeviceUUID(), mVideodetectionAndAccelerometerViewModel.getSystemTimeStamp(), false, "VideoAndAccelerometer", 0); } - } }); diff --git a/app/src/main/java/com/example/greenwatch/sensors/CameraSensor.java b/app/src/main/java/com/example/greenwatch/sensors/CameraSensor.java index 47cd07f..c238df8 100644 --- a/app/src/main/java/com/example/greenwatch/sensors/CameraSensor.java +++ b/app/src/main/java/com/example/greenwatch/sensors/CameraSensor.java @@ -3,6 +3,7 @@ package com.example.greenwatch.sensors; import android.content.Context; import android.graphics.ImageFormat; import android.media.Image; +import android.os.Handler; import android.util.Size; import androidx.camera.core.CameraSelector; @@ -18,9 +19,18 @@ public class CameraSensor { private final MutableLiveData mVideoAlarmDetected = new MutableLiveData<>(); private static CameraSensor cameraSensorInstance; private boolean videoAlarmDetected; + private boolean isMotionDetected; private ByteBuffer previousBuffer; private int previousWidth; private int previousHeight; + private final int threshold = 50; + private int startX; + private int startY; + private int endX; + private int endY; + private static final long ALARM_RESET_DELAY = 5000; + private Runnable alarmResetRunnable; + private final Handler alarmResetHandler = new Handler(); private CameraSensor() { videoAlarmDetected = false; @@ -59,7 +69,7 @@ public class CameraSensor { if (previousHeight != 0) { assert currentImage != null; - videoAlarmDetected = compareFrames(currentImage); + isMotionDetected = compareFrames(currentImage); } assert currentImage != null; @@ -72,6 +82,18 @@ public class CameraSensor { currentImage.close(); + if (isMotionDetected) { + + videoAlarmDetected = true; + + if(alarmResetRunnable != null) { + alarmResetHandler.removeCallbacks(alarmResetRunnable); + } + + alarmResetRunnable = this::resetAlarmStatus; + alarmResetHandler.postDelayed(alarmResetRunnable, ALARM_RESET_DELAY); + } + checkAlarmCondition(); } @@ -85,36 +107,76 @@ public class CameraSensor { } private boolean compareFrames(Image currentImage) { - - ByteBuffer currentBuffer = currentImage.getPlanes()[0].getBuffer(); - + Image.Plane[] planes = currentImage.getPlanes(); + ByteBuffer currentBuffer = planes[0].getBuffer(); int currentWidth = currentImage.getWidth(); int currentHeight = currentImage.getHeight(); + int yRowStride = planes[0].getRowStride(); + int yPixelStride = planes[0].getPixelStride(); if (previousWidth != currentWidth || previousHeight != currentHeight) { return false; } - for (int row = 0; row < previousHeight; row++) { - for (int col = 0; col < previousWidth; col++) { + int blockSize = kleinstesQuadrat(previousHeight, previousWidth) / 8; - int previousIndex = row * previousWidth + col; - int currentIndex = row * currentWidth + col; + int numBlocksX = currentWidth / blockSize; + int numBlocksY = currentHeight / blockSize; - int previousPixel = previousBuffer.get(previousIndex) & 0xFF; - int currentPixel = currentBuffer.get(currentIndex) & 0xFF; + for (int blockY = 0; blockY < numBlocksY; blockY++) { + for (int blockX = 0; blockX < numBlocksX; blockX++) { + startX = blockX * blockSize; + startY = blockY * blockSize; + endX = startX + blockSize; + endY = startY + blockSize; - int pixelDifference = Math.abs(previousPixel - currentPixel); - int threshold = 120; + float currentLuminance = berechneMittlereLuminanz(currentBuffer, yRowStride, yPixelStride); + float previousLuminance = berechneMittlereLuminanz(previousBuffer, yRowStride, yPixelStride); + + int pixelDifference = Math.abs((int) previousLuminance - (int) currentLuminance); if (pixelDifference > threshold) { + System.out.println(pixelDifference); return true; } } } + return false; } + private float berechneMittlereLuminanz(ByteBuffer buffer, int rowStride, int pixelStride) { + int sumLuminance = 0; + int countPixels = 0; + + for (int row = startY; row < endY; row++) { + for (int col = startX; col < endX; col++) { + int bufferIndex = row * rowStride + col * pixelStride; + int currentPixel = buffer.get(bufferIndex) & 0xFF; + + sumLuminance += currentPixel; + countPixels++; + } + } + + return (float) sumLuminance / countPixels; + } + + private int kleinstesQuadrat(int height, int width) { + if (height == width) { + return height; + } else if (height > width) { + return kleinstesQuadrat(height - width, width); + } else { + return kleinstesQuadrat(height, width - height); + } + } + + private void resetAlarmStatus() { + videoAlarmDetected = false; + alarmResetRunnable = null; + } + public void checkAlarmCondition() { if (videoAlarmDetected && !mVideoAlarmDetected.getValue()) { setMutableLiveDataVideoAlarmDetected(); diff --git a/app/src/main/java/com/example/greenwatch/viewmodels/VideodetectionAndAccelerometerViewModel.java b/app/src/main/java/com/example/greenwatch/viewmodels/VideodetectionAndAccelerometerViewModel.java index 79d7500..ac290a8 100644 --- a/app/src/main/java/com/example/greenwatch/viewmodels/VideodetectionAndAccelerometerViewModel.java +++ b/app/src/main/java/com/example/greenwatch/viewmodels/VideodetectionAndAccelerometerViewModel.java @@ -26,7 +26,9 @@ public class VideodetectionAndAccelerometerViewModel extends ViewModel implement private AccelerometerSensor mAccelerometerSensor; private CameraSensor mCameraSensor; private DeviceRepository mDeviceRepository; - private boolean VideodetectionAndAccelerometerAlarmDetected; + private boolean videoAlarmDetected; + private boolean accelerometerAlarmDetected; + private boolean videodetectionAndAccelerometerAlarmDetected; @Override public void init() { @@ -54,7 +56,9 @@ public class VideodetectionAndAccelerometerViewModel extends ViewModel implement if (mVideoAlarmDetected == null) { mVideoAlarmDetected = mCameraSensor.getVideoAlarmDetectedValue(); } - VideodetectionAndAccelerometerAlarmDetected = false; + videodetectionAndAccelerometerAlarmDetected = false; + videoAlarmDetected = false; + accelerometerAlarmDetected = false; registerAlarmObserver(); } @@ -84,19 +88,37 @@ public class VideodetectionAndAccelerometerViewModel extends ViewModel implement } private void setMutableLiveDataVideodetectionAndAccelerometerAlarmDetected() { - mVideodetectionAndAccelerometerAlarmDetected.setValue(VideodetectionAndAccelerometerAlarmDetected); + mVideodetectionAndAccelerometerAlarmDetected.setValue(videodetectionAndAccelerometerAlarmDetected); + } + + private void setAccelerometerAlarmDetected(boolean accelerometerAlarmDetected) { + this.accelerometerAlarmDetected = accelerometerAlarmDetected; + } + + public boolean getAccelerometerAlarmDetected() { + return accelerometerAlarmDetected; + } + + private void setVideoAlarmDetected(boolean videoAlarmDetected) { + this.videoAlarmDetected = videoAlarmDetected; + } + + public boolean getVideoAlarmDetected() { + return videoAlarmDetected; } Observer observer = new Observer() { @Override public void onChanged(Boolean aBoolean) { - if (mVideoAlarmDetected.getValue() || mAccelerometerAlarmDetected.getValue() && !VideodetectionAndAccelerometerAlarmDetected) { - VideodetectionAndAccelerometerAlarmDetected = true; + setAccelerometerAlarmDetected(mAccelerometerAlarmDetected.getValue()); + setVideoAlarmDetected(mVideoAlarmDetected.getValue()); + if (videoAlarmDetected || accelerometerAlarmDetected && !videodetectionAndAccelerometerAlarmDetected) { + videodetectionAndAccelerometerAlarmDetected = true; setMutableLiveDataVideodetectionAndAccelerometerAlarmDetected(); } - else if (!mVideoAlarmDetected.getValue() && !mAccelerometerAlarmDetected.getValue() && VideodetectionAndAccelerometerAlarmDetected) { - VideodetectionAndAccelerometerAlarmDetected = false; + else if (!videoAlarmDetected && !accelerometerAlarmDetected && videodetectionAndAccelerometerAlarmDetected) { + videodetectionAndAccelerometerAlarmDetected = false; setMutableLiveDataVideodetectionAndAccelerometerAlarmDetected(); } }