You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CameraSensor.java 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package com.example.greenwatch.sensors;
  2. import android.content.Context;
  3. import android.graphics.ImageFormat;
  4. import android.media.Image;
  5. import android.util.Size;
  6. import androidx.camera.core.CameraSelector;
  7. import androidx.camera.core.ImageAnalysis;
  8. import androidx.camera.lifecycle.ProcessCameraProvider;
  9. import androidx.core.content.ContextCompat;
  10. import androidx.lifecycle.LifecycleOwner;
  11. import androidx.lifecycle.MutableLiveData;
  12. import java.nio.ByteBuffer;
  13. public class CameraSensor {
  14. private final MutableLiveData<Boolean> mVideoAlarmDetected = new MutableLiveData<>();
  15. private static CameraSensor cameraSensorInstance;
  16. private boolean videoAlarmDetected;
  17. private ByteBuffer previousBuffer;
  18. private int previousWidth;
  19. private int previousHeight;
  20. private CameraSensor() {
  21. videoAlarmDetected = false;
  22. }
  23. public static synchronized CameraSensor getInstance() {
  24. if (cameraSensorInstance == null){
  25. cameraSensorInstance = new CameraSensor();
  26. }
  27. return cameraSensorInstance;
  28. }
  29. public MutableLiveData<Boolean> getVideoAlarmDetectedValue() {
  30. setMutableLiveDataVideoAlarmDetected();
  31. return mVideoAlarmDetected;
  32. }
  33. private void setMutableLiveDataVideoAlarmDetected() {
  34. mVideoAlarmDetected.setValue(videoAlarmDetected);
  35. }
  36. public void bindImageAnalysis(ProcessCameraProvider cameraProvider, LifecycleOwner lifecycleOwner, Context context) {
  37. ImageAnalysis.Builder builder = new ImageAnalysis.Builder();
  38. builder.setTargetResolution(new Size(640, 480));
  39. builder.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST);
  40. ImageAnalysis imageAnalysis = builder.build();
  41. imageAnalysis.setAnalyzer(
  42. ContextCompat.getMainExecutor(context),
  43. imageProxy -> {
  44. int imageFormat = imageProxy.getFormat();
  45. if (imageFormat == ImageFormat.YUV_420_888) {
  46. Image currentImage = imageProxy.getImage();
  47. if (previousHeight != 0) {
  48. assert currentImage != null;
  49. videoAlarmDetected = compareFrames(currentImage);
  50. }
  51. assert currentImage != null;
  52. Image.Plane[] planes = currentImage.getPlanes();
  53. ByteBuffer buffer = planes[0].getBuffer().duplicate();
  54. previousBuffer = ByteBuffer.allocateDirect(buffer.remaining());
  55. previousBuffer.put(buffer);
  56. previousWidth = currentImage.getWidth();
  57. previousHeight = currentImage.getHeight();
  58. currentImage.close();
  59. checkAlarmCondition();
  60. }
  61. imageProxy.close();
  62. });
  63. CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
  64. cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, imageAnalysis);
  65. }
  66. private boolean compareFrames(Image currentImage) {
  67. ByteBuffer currentBuffer = currentImage.getPlanes()[0].getBuffer();
  68. int currentWidth = currentImage.getWidth();
  69. int currentHeight = currentImage.getHeight();
  70. if (previousWidth != currentWidth || previousHeight != currentHeight) {
  71. return false;
  72. }
  73. for (int row = 0; row < previousHeight; row++) {
  74. for (int col = 0; col < previousWidth; col++) {
  75. int previousIndex = row * previousWidth + col;
  76. int currentIndex = row * currentWidth + col;
  77. int previousPixel = previousBuffer.get(previousIndex) & 0xFF;
  78. int currentPixel = currentBuffer.get(currentIndex) & 0xFF;
  79. int pixelDifference = Math.abs(previousPixel - currentPixel);
  80. int threshold = 120;
  81. if (pixelDifference > threshold) {
  82. return true;
  83. }
  84. }
  85. }
  86. return false;
  87. }
  88. public void checkAlarmCondition() {
  89. if (videoAlarmDetected && !mVideoAlarmDetected.getValue()) {
  90. setMutableLiveDataVideoAlarmDetected();
  91. }
  92. else if (!videoAlarmDetected && mVideoAlarmDetected.getValue()){
  93. setMutableLiveDataVideoAlarmDetected();
  94. }
  95. }
  96. }