155 lines
3.8 KiB
Dart
155 lines
3.8 KiB
Dart
import 'dart:async';
|
|
import 'dart:ffi';
|
|
import 'package:camera/camera.dart';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
List<CameraDescription> cameras = [];
|
|
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
cameras = await availableCameras();
|
|
runApp(CameraApp());
|
|
}
|
|
|
|
class CameraApp extends StatefulWidget {
|
|
@override
|
|
_CameraAppState createState() => _CameraAppState();
|
|
}
|
|
|
|
class _CameraAppState extends State<CameraApp> {
|
|
CameraController? controller;
|
|
var streaming = false;
|
|
var image_width = 0;
|
|
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;
|
|
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
controller = CameraController(cameras[1], ResolutionPreset.low);
|
|
controller!.initialize().then((_) {
|
|
if (!mounted) {
|
|
return;
|
|
}
|
|
setState(() {});
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
controller?.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final CameraController cameraController = controller!;
|
|
if (!cameraController.value.isInitialized) {
|
|
return Container();
|
|
}
|
|
|
|
return MaterialApp(
|
|
home: Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text('Home'),
|
|
),
|
|
body: Column(children: <Widget>[
|
|
CameraPreview(cameraController),
|
|
]),
|
|
floatingActionButton: FloatingActionButton(
|
|
child: const Icon(Icons.plus_one),
|
|
onPressed: () {
|
|
startStream();
|
|
},
|
|
),
|
|
),
|
|
debugShowCheckedModeBanner: false,
|
|
);
|
|
}
|
|
|
|
void startStream() {
|
|
final CameraController? cameraController = controller;
|
|
|
|
if (cameraController == null || !cameraController.value.isInitialized) {
|
|
return;
|
|
}
|
|
|
|
if (streaming == false) {
|
|
cameraController.startImageStream(handleImage);
|
|
} else {
|
|
cameraController.stopImageStream();
|
|
}
|
|
|
|
setState(() {
|
|
streaming = !streaming;
|
|
});
|
|
}
|
|
|
|
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);
|
|
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));
|
|
|
|
//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];
|
|
}
|
|
}
|
|
}
|
|
// 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];
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|