diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..42dadb5 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "reprecord-app", + "request": "launch", + "type": "dart" + }, + { + "name": "reprecord-app (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + } + ] +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 66dbfaa..641384e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,10 +1,13 @@ import 'dart:async'; import 'dart:ffi'; -import 'package:camera/camera.dart'; +import 'dart:ui'; import 'dart:typed_data'; - +import 'dart:math'; import 'package:flutter/material.dart'; +import 'package:camera/camera.dart'; +import 'package:image/image.dart' as img; + List cameras = []; Future main() async { @@ -26,16 +29,16 @@ class _CameraAppState extends State { var image_height = 0; var posy = 0.0; var posx = 0.0; - var count = 0.0; - static const alpha = 0.99; - static const thresh = 25; - Uint8List? previousImage; - Uint8List? diff; - Uint8List? dst; - Uint64List? diffValues; - Float32List? background; - Float64List? diffWeightsX; - + var count = 0; + var frameNumber = 0; + static const alpha = 0.90; + static const thresh = 50; + + var previousImage = []; + var gray = []; + var diff = []; + var dst = []; + var background = []; @override void initState() { @@ -67,8 +70,15 @@ class _CameraAppState extends State { appBar: AppBar( title: const Text('Home'), ), - body: Column(children: [ - CameraPreview(cameraController), + body: Stack(children: [ + diffView(), + Container( + height: image_height.toDouble(), + width: image_width.toDouble(), + child: CustomPaint( + painter: OpenPainter(posx, posy), + ), + ), ]), floatingActionButton: FloatingActionButton( child: const Icon(Icons.plus_one), @@ -81,6 +91,17 @@ class _CameraAppState extends State { ); } + Widget diffView() { + return Transform.rotate( + angle: 0.0, //pi * -0.5 + child: diff.isEmpty + ? Container() + : Image.memory(Uint8List.fromList(img.encodeJpg((img.Image.fromBytes( + image_width, image_height, diff, + format: img.Format.luminance))))), + ); + } + void startStream() { final CameraController? cameraController = controller; @@ -99,56 +120,62 @@ class _CameraAppState extends State { }); } - void handleImage(CameraImage src) { - diffWeightsX = Float64List(src.width); - diffValues = Uint64List(src.width); - - if (previousImage == null || background == null) { - previousImage = Uint8List(src.planes[0].bytes.length); - dst = Uint8List(src.planes[0].bytes.length); - diff = Uint8List(src.planes[0].bytes.length); - background = Float32List(src.planes[0].bytes.length); + void handleImage(CameraImage src) async { + if (previousImage.isEmpty) { + previousImage = List.filled(src.planes[0].bytes.length, 0); + gray = List.filled(src.planes[0].bytes.length, 0); + diff = List.filled(src.planes[0].bytes.length, 0); + dst = List.filled(src.planes[0].bytes.length, 0); + background = List.filled(src.planes[0].bytes.length, 0.0); + image_width = src.width; image_height = src.height; } else { - for (var i = 0; i < image_height; i++) { - for (var j = 0; j < image_width; j++) { - //Background calculation - background![i + j] = (background![i + j] * alpha + - src.planes[0].bytes[i + j].toDouble() * (1.0 - alpha)); + if (frameNumber % 10 == 0) { + gray = src.planes[0].bytes; - //Difference calculation - diff![i + j] = (background![i + j].toInt() - src.planes[0].bytes[i + j]).abs(); - if(diff![i + j] > thresh) { - diffWeightsX![i] += diff![i + j] * j; - diffValues![i] += diff![i + j]; + count = 0; + var xVal = 0.0; + var yVal = 0.0; + + for (var i = 0; i < gray.length; i++) { + background[i] = background[i] * alpha + gray[i] * (1.0 - alpha); + diff[i] = (gray[i] - background[i].toInt()).abs(); + dst[i] = background[i].toInt(); + if (diff[i] < thresh) { + diff[i] = 0; + } else { + //diff[i] = 255; + xVal += diff[i] * ((i % image_width) + 1); + yVal += diff[i] * ((i % image_height) + 1); + count += diff[i]; } } - } - // Processing - //Average X Position - posx = 0; - posy = 0; - var currentCount = 0; - var weightsY = 0; - for(var i = 0; i < diffWeightsX!.length; i++){ - if(diffValues![i] > 0){ - posx += (diffWeightsX![i]/diffValues![i])/diffWeightsX!.length; - weightsY += diffValues![i] * i; - currentCount += diffValues![i]; + // End Processing + previousImage = gray.toList(); + if (count != 0) { + posx = xVal / count; + posy = yVal / count; + print("$count ${posx.toInt()} ${posy.toInt()}"); } + setState(() {}); } - - if(currentCount > 0) { - posy = weightsY/currentCount; - } - - count = count * alpha + (currentCount/(image_width * image_height * 255) * 100.0) * (1.0 - alpha); - print(count); - - // End Processing - previousImage = src.planes[0].bytes; + frameNumber += 1; } } } + +class OpenPainter extends CustomPainter { + double posx; + double posy; + OpenPainter(this.posx, this.posy); + @override + void paint(Canvas canvas, Size size) { + canvas.drawCircle(Offset(posx, posy), 10, + Paint()..color = Color.fromARGB(255, 0, 255, 0)); + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} diff --git a/pubspec.lock b/pubspec.lock index c8aa58e..e6b8862 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,13 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.6" async: dependency: transitive description: @@ -71,6 +78,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.3.2" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" fake_async: dependency: transitive description: @@ -107,6 +121,13 @@ packages: description: flutter source: sdk version: "0.0.0" + image: + dependency: "direct main" + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.8" js: dependency: transitive description: @@ -149,6 +170,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.11.1" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "4.4.0" plugin_platform_interface: dependency: transitive description: @@ -231,6 +259,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "5.3.1" sdks: dart: ">=2.14.0 <3.0.0" flutter: ">=2.5.0" diff --git a/pubspec.yaml b/pubspec.yaml index 00524fe..664d04a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,6 +11,7 @@ dependencies: camera: ^0.9.4+3 flutter: sdk: flutter + image: ^3.0.8 dev_dependencies: flutter_test: