Kamera um neue Detektion ergänzt

Timer zum besseren Alarm Handling ergänzt
This commit is contained in:
Michael Pilhoefer 2023-06-20 11:47:24 +02:00
parent 8dd4c6d56a
commit fad1ed3937

View File

@ -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,19 @@ public class CameraSensor {
private final MutableLiveData<Boolean> 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 +70,7 @@ public class CameraSensor {
if (previousHeight != 0) {
assert currentImage != null;
videoAlarmDetected = compareFrames(currentImage);
isMotionDetected = compareFrames(currentImage);
}
assert currentImage != null;
@ -72,6 +83,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 +108,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()) {
setMutableLiveDataVideoMovementDetected();