capacitor-plugin-camera-forked 3.1.121 → 3.1.123

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -56,7 +56,7 @@ import java.util.concurrent.atomic.AtomicReference;
56
56
  public class BlurDetectionHelper {
57
57
  private static final String TAG = "BlurDetectionHelper";
58
58
  private static final String MODEL_FILENAME = "blur_detection_model.tflite";
59
- private static int INPUT_SIZE = 224; // Will be updated based on actual model input size
59
+ private static int INPUT_SIZE = 600; // Will be updated based on actual model input size
60
60
  private static final int NUM_CLASSES = 2; // blur, sharp
61
61
 
62
62
  // Timeout settings
@@ -66,6 +66,11 @@ public class BlurDetectionHelper {
66
66
  private static final double MIN_WORD_CONFIDENCE = 0.8; // 80% confidence threshold
67
67
  private static final double AT_LEAST_N_PERCENT_OF_WORDS_ARE_READABLE = 0.6; // 60% of words are readable
68
68
  private static final double AT_LEAST_N_PERCENT_OF_AVERAGE_CONFIDENCE = 0.85; // 85% of average confidence
69
+
70
+ // Method based confidence threshold
71
+ private static final double MIN_SHARP_CONFIDENCE_FOR_OBJECT_DETECTION = 0.75; // 75% confidence threshold
72
+ private static final double MIN_SHARP_CONFIDENCE_FOR_TEXT_DETECTION = 0.15; // 15% confidence threshold
73
+ private static final double MIN_SHARP_CONFIDENCE_FOR_FULL_IMAGE = 0.75; // 70% confidence threshold
69
74
 
70
75
  // TFLite components
71
76
  private Interpreter tflite;
@@ -91,10 +96,9 @@ public class BlurDetectionHelper {
91
96
 
92
97
 
93
98
  public BlurDetectionHelper() {
94
- // Initialize image processor for MobileNetV2 preprocessing
99
+ // Initialize image processor for MobileNetV2 preprocessing with aspect ratio preservation
95
100
  imageProcessor = new ImageProcessor.Builder()
96
- .add(new ResizeWithCropOrPadOp(INPUT_SIZE, INPUT_SIZE))
97
- .add(new ResizeOp(INPUT_SIZE, INPUT_SIZE, ResizeOp.ResizeMethod.BILINEAR))
101
+ .add(new ResizeWithCropOrPadOp(INPUT_SIZE, INPUT_SIZE)) // This preserves aspect ratio by cropping/padding
98
102
  .build();
99
103
 
100
104
  // Initialize common words dictionary
@@ -146,10 +150,9 @@ public class BlurDetectionHelper {
146
150
  if (modelInputSize != INPUT_SIZE) {
147
151
  INPUT_SIZE = modelInputSize;
148
152
 
149
- // Recreate image processor with correct size
153
+ // Recreate image processor with correct size and aspect ratio preservation
150
154
  imageProcessor = new ImageProcessor.Builder()
151
- .add(new ResizeWithCropOrPadOp(INPUT_SIZE, INPUT_SIZE))
152
- .add(new ResizeOp(INPUT_SIZE, INPUT_SIZE, ResizeOp.ResizeMethod.BILINEAR))
155
+ .add(new ResizeWithCropOrPadOp(INPUT_SIZE, INPUT_SIZE)) // Preserves aspect ratio
153
156
  .build();
154
157
  }
155
158
  }
@@ -239,7 +242,7 @@ public class BlurDetectionHelper {
239
242
  Bitmap roi = cropBitmap(bitmap, boundingBox);
240
243
  if (roi != null) {
241
244
  // Run TFLite blur detection on ROI
242
- Map<String, Object> roiResult = detectBlurWithTFLiteConfidence(roi);
245
+ Map<String, Object> roiResult = detectBlurWithTFLiteConfidence(roi, MIN_SHARP_CONFIDENCE_FOR_OBJECT_DETECTION);
243
246
 
244
247
  Log.d(TAG, "Object Detection ROI Result isBlur: " + roiResult.get("isBlur"));
245
248
  roiResult.put("boundingBox", boundingBox);
@@ -299,7 +302,7 @@ public class BlurDetectionHelper {
299
302
 
300
303
  // Step 3: Full-Image Blur Detection (Final Fallback)
301
304
  Log.d(TAG, "Step 3: Using Full-Image Blur Detection");
302
- return detectBlurWithTFLiteConfidence(bitmap);
305
+ return detectBlurWithTFLiteConfidence(bitmap, MIN_SHARP_CONFIDENCE_FOR_FULL_IMAGE);
303
306
 
304
307
  } catch (Exception e) {
305
308
  Log.e(TAG, "Error in blur detection pipeline: " + e.getMessage());
@@ -329,6 +332,9 @@ public class BlurDetectionHelper {
329
332
  // Preprocess image for model (resize and potential enhancement)
330
333
  inputImageBuffer.load(processedBitmap);
331
334
  inputImageBuffer = imageProcessor.process(inputImageBuffer);
335
+
336
+ // Ensure black padding for better accuracy (matches iOS implementation)
337
+ ensureBlackPadding(inputImageBuffer);
332
338
 
333
339
  // Get tensor buffer
334
340
  ByteBuffer tensorBuffer = inputImageBuffer.getBuffer();
@@ -355,7 +361,7 @@ public class BlurDetectionHelper {
355
361
  double sharpConfidence = probabilities.length > 1 ? probabilities[1] : 0.0;
356
362
 
357
363
  // Determine if image is blurry using TFLite confidence
358
- boolean isBlur = sharpConfidence < 0.80;
364
+ boolean isBlur = sharpConfidence < MIN_SHARP_CONFIDENCE_FOR_FULL_IMAGE;
359
365
 
360
366
 
361
367
  // Return 1.0 for blur, 0.0 for sharp (to maintain double return type)
@@ -420,6 +426,37 @@ public class BlurDetectionHelper {
420
426
  return normalizedBuffer;
421
427
  }
422
428
 
429
+ /**
430
+ * Ensure black padding in the processed image buffer for better accuracy
431
+ * @param tensorImage Processed tensor image
432
+ */
433
+ private void ensureBlackPadding(TensorImage tensorImage) {
434
+ ByteBuffer buffer = tensorImage.getBuffer();
435
+ DataType dataType = tensorImage.getDataType();
436
+
437
+ if (dataType == DataType.FLOAT32) {
438
+ // For float32, ensure padding areas are 0.0 (black)
439
+ FloatBuffer floatBuffer = buffer.asFloatBuffer();
440
+ int totalPixels = INPUT_SIZE * INPUT_SIZE * 3;
441
+
442
+ // Check if we need to fill with zeros (black)
443
+ for (int i = 0; i < totalPixels; i++) {
444
+ if (floatBuffer.get(i) < 0.001f) { // Near zero values
445
+ floatBuffer.put(i, 0.0f); // Ensure exact zero (black)
446
+ }
447
+ }
448
+ } else if (dataType == DataType.UINT8) {
449
+ // For uint8, ensure padding areas are 0 (black)
450
+ buffer.rewind();
451
+ while (buffer.hasRemaining()) {
452
+ byte value = buffer.get();
453
+ if (value == 0) {
454
+ buffer.put(buffer.position() - 1, (byte) 0); // Ensure exact zero
455
+ }
456
+ }
457
+ }
458
+ }
459
+
423
460
  /**
424
461
  * Normalize image buffer from uint8 [0,255] to float32 [0,1]
425
462
  * @param uint8Buffer Input buffer with uint8 pixel values
@@ -498,7 +535,7 @@ public class BlurDetectionHelper {
498
535
  * @param bitmap Input image bitmap
499
536
  * @return Map with isBlur, blurConfidence, and sharpConfidence
500
537
  */
501
- public java.util.Map<String, Object> detectBlurWithTFLiteConfidence(Bitmap bitmap) {
538
+ public java.util.Map<String, Object> detectBlurWithTFLiteConfidence(Bitmap bitmap, double minSharpConfidence) {
502
539
  java.util.Map<String, Object> result = new java.util.HashMap<>();
503
540
 
504
541
  if (!isInitialized || tflite == null) {
@@ -525,6 +562,9 @@ public class BlurDetectionHelper {
525
562
  // Preprocess image for model (resize and potential enhancement)
526
563
  inputImageBuffer.load(processedBitmap);
527
564
  inputImageBuffer = imageProcessor.process(inputImageBuffer);
565
+
566
+ // Ensure black padding for better accuracy (matches iOS implementation)
567
+ ensureBlackPadding(inputImageBuffer);
528
568
 
529
569
  // Get tensor buffer
530
570
  ByteBuffer tensorBuffer = inputImageBuffer.getBuffer();
@@ -553,7 +593,7 @@ public class BlurDetectionHelper {
553
593
  Log.d(TAG, "TFLite Blur confidence: " + blurConfidence + " Sharp confidence: " + sharpConfidence);
554
594
 
555
595
  // Determine if image is blurry using TFLite confidence
556
- boolean isBlur = sharpConfidence < 0.80;
596
+ boolean isBlur = sharpConfidence < minSharpConfidence;
557
597
 
558
598
  Log.d(TAG, "TFLite Blur detection isBlur: " + isBlur);
559
599
 
@@ -783,7 +823,7 @@ public class BlurDetectionHelper {
783
823
  try {
784
824
  Bitmap cropped = cropBitmap(bitmap, roi);
785
825
  if (cropped != null) {
786
- Map<String, Object> result = detectBlurWithTFLiteConfidence(cropped);
826
+ Map<String, Object> result = detectBlurWithTFLiteConfidence(cropped, MIN_SHARP_CONFIDENCE_FOR_TEXT_DETECTION);
787
827
  result.put("boundingBox", roi);
788
828
  results.add(result);
789
829
  }
@@ -12,8 +12,8 @@ import MLKitVision
12
12
  class BlurDetectionHelper {
13
13
 
14
14
  private static let TAG = "BlurDetectionHelper"
15
- private static let INPUT_WIDTH = 224 // Model's expected input width
16
- private static let INPUT_HEIGHT = 224 // Model's expected input height
15
+ private static let INPUT_WIDTH = 600 // Model's expected input width
16
+ private static let INPUT_HEIGHT = 600 // Model's expected input height
17
17
  private static let BATCH_SIZE = 1 // Model expects a batch size of 1
18
18
  private static let NUM_CHANNELS = 3 // RGB
19
19
  private static let NUM_CLASSES = 2 // blur, sharp
@@ -27,10 +27,10 @@ class BlurDetectionHelper {
27
27
  private static let AT_LEAST_N_PERCENT_OF_AVERAGE_CONFIDENCE: Double = 0.85 // 85% of average confidence
28
28
 
29
29
  // Method based confidence threshold
30
- private static let MIN_SHARP_CONFIDENCE_FOR_OBJECT_DETECTION: Double = 0.4 // 40% confidence threshold
31
- private static let MIN_SHARP_CONFIDENCE_FOR_TEXT_DETECTION: Double = 0.1 // 10% confidence threshold
32
- private static let MIN_SHARP_CONFIDENCE_FOR_FULL_IMAGE: Double = 0.7 // 70% confidence threshold
33
-
30
+ private static let MIN_SHARP_CONFIDENCE_FOR_OBJECT_DETECTION: Double = 0.75 // 75% confidence threshold
31
+ private static let MIN_SHARP_CONFIDENCE_FOR_TEXT_DETECTION: Double = 0.15 // 15% confidence threshold
32
+ private static let MIN_SHARP_CONFIDENCE_FOR_FULL_IMAGE: Double = 0.75 // 75% confidence threshold
33
+
34
34
  private var interpreter: Interpreter?
35
35
  private var isInitialized = false
36
36
 
@@ -391,11 +391,37 @@ class BlurDetectionHelper {
391
391
  }
392
392
 
393
393
  /**
394
- * Resize image to target size
394
+ * Resize image to target size while maintaining aspect ratio
395
395
  */
396
396
  private func resizeImage(_ image: UIImage, to size: CGSize) -> UIImage? {
397
- UIGraphicsBeginImageContextWithOptions(size, false, 1.0)
398
- image.draw(in: CGRect(origin: .zero, size: size))
397
+ let targetSize = size
398
+ let imageSize = image.size
399
+
400
+ // Calculate aspect ratio preserving dimensions
401
+ let widthRatio = targetSize.width / imageSize.width
402
+ let heightRatio = targetSize.height / imageSize.height
403
+ let scaleFactor = min(widthRatio, heightRatio)
404
+
405
+ let scaledSize = CGSize(
406
+ width: imageSize.width * scaleFactor,
407
+ height: imageSize.height * scaleFactor
408
+ )
409
+
410
+ // Create a square canvas with the target size
411
+ UIGraphicsBeginImageContextWithOptions(targetSize, false, 1.0)
412
+
413
+ // Calculate position to center the scaled image
414
+ let x = (targetSize.width - scaledSize.width) / 2
415
+ let y = (targetSize.height - scaledSize.height) / 2
416
+ let drawRect = CGRect(x: x, y: y, width: scaledSize.width, height: scaledSize.height)
417
+
418
+ // Fill background with black (or white) to pad the image
419
+ UIColor.black.setFill()
420
+ UIRectFill(CGRect(origin: .zero, size: targetSize))
421
+
422
+ // Draw the scaled image centered
423
+ image.draw(in: drawRect)
424
+
399
425
  let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
400
426
  UIGraphicsEndImageContext()
401
427
  return resizedImage
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-plugin-camera-forked",
3
- "version": "3.1.121",
3
+ "version": "3.1.123",
4
4
  "description": "A capacitor camera plugin - A custom Capacitor camera plugin with additional features.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",