|
@@ -16,12 +16,18 @@ class FaceBoundingBox extends GetView<FacialRecognitionController> {
|
|
|
}
|
|
|
return Container(
|
|
|
padding: const EdgeInsets.all(10),
|
|
|
- child: CustomPaint(
|
|
|
- size: Size.infinite,
|
|
|
- painter: _FaceBoundingBoxPainter(
|
|
|
- faces: controller.facesResult,
|
|
|
- ),
|
|
|
- ),
|
|
|
+ child: GetBuilder<FacialRecognitionController>(
|
|
|
+ id: 'face_bounding_box',
|
|
|
+ builder: (context) {
|
|
|
+ return CustomPaint(
|
|
|
+ size: Size.infinite,
|
|
|
+ painter: _FaceBoundingBoxPainter(
|
|
|
+ faces: controller.kFrameFacesResult,
|
|
|
+ sourceImageSize: controller.kFrameImageSize,
|
|
|
+ isMirror: true,
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }),
|
|
|
);
|
|
|
});
|
|
|
}
|
|
@@ -30,30 +36,31 @@ class FaceBoundingBox extends GetView<FacialRecognitionController> {
|
|
|
class _FaceBoundingBoxPainter extends CustomPainter {
|
|
|
final List<Face> faces;
|
|
|
|
|
|
- _FaceBoundingBoxPainter({required this.faces});
|
|
|
+ /// 是否镜像
|
|
|
+ final bool isMirror;
|
|
|
+
|
|
|
+ /// 原始图片大小
|
|
|
+ final Size sourceImageSize;
|
|
|
+
|
|
|
+ _FaceBoundingBoxPainter(
|
|
|
+ {required this.faces,
|
|
|
+ required this.isMirror,
|
|
|
+ required this.sourceImageSize});
|
|
|
|
|
|
@override
|
|
|
void paint(Canvas canvas, Size size) {
|
|
|
- final paint = Paint()
|
|
|
- ..color = Colors.red
|
|
|
- ..strokeWidth = 3
|
|
|
- ..style = PaintingStyle.stroke;
|
|
|
-
|
|
|
- final contourPaint = Paint()
|
|
|
- ..color = Colors.red
|
|
|
- ..strokeWidth = 2
|
|
|
- ..style = PaintingStyle.stroke;
|
|
|
+ // 根据原始图片大小和当前画布大小,计算缩放比例
|
|
|
+ final scaleX = size.width / sourceImageSize.width;
|
|
|
+ final scaleY = size.height / sourceImageSize.height;
|
|
|
+ if (isMirror) {
|
|
|
+ canvas.scale(-scaleX, scaleY);
|
|
|
+ canvas.translate(-sourceImageSize.width, 0);
|
|
|
+ } else {
|
|
|
+ canvas.scale(scaleX, scaleY);
|
|
|
+ canvas.translate(0, 0);
|
|
|
+ }
|
|
|
|
|
|
for (final face in faces) {
|
|
|
- // 将 rect 内参数左右镜像翻转
|
|
|
- // final newRect = Rect.fromLTWH(
|
|
|
- // size.width - face.boundingBox.right,
|
|
|
- // face.boundingBox.top,
|
|
|
- // face.boundingBox.width,
|
|
|
- // face.boundingBox.height,
|
|
|
- // );
|
|
|
- // canvas.drawRect(newRect, paint);
|
|
|
-
|
|
|
/// 绘制关键点
|
|
|
for (final FaceContour? contour in face.contours.values) {
|
|
|
if (contour == null) continue;
|
|
@@ -64,6 +71,9 @@ class _FaceBoundingBoxPainter extends CustomPainter {
|
|
|
_drawContourPoints(canvas, size, contour.points);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /// 绘制人脸框
|
|
|
+ _drawFaceRect(canvas, size, face.boundingBox);
|
|
|
}
|
|
|
|
|
|
/// 全屏画绿色
|
|
@@ -73,7 +83,7 @@ class _FaceBoundingBoxPainter extends CustomPainter {
|
|
|
..style = PaintingStyle.stroke;
|
|
|
|
|
|
canvas.drawRect(
|
|
|
- Rect.fromLTWH(0, 0, size.width, size.height),
|
|
|
+ Rect.fromLTWH(0, 0, sourceImageSize.width, sourceImageSize.height),
|
|
|
paint2,
|
|
|
);
|
|
|
}
|
|
@@ -91,13 +101,13 @@ class _FaceBoundingBoxPainter extends CustomPainter {
|
|
|
final point = points[i];
|
|
|
if (i == 0) {
|
|
|
path.moveTo(
|
|
|
- size.width - point.x,
|
|
|
+ point.x.toDouble(),
|
|
|
point.y.toDouble(),
|
|
|
);
|
|
|
continue;
|
|
|
}
|
|
|
path.lineTo(
|
|
|
- size.width - point.x,
|
|
|
+ point.x.toDouble(),
|
|
|
point.y.toDouble(),
|
|
|
);
|
|
|
}
|
|
@@ -115,7 +125,7 @@ class _FaceBoundingBoxPainter extends CustomPainter {
|
|
|
for (final point in points) {
|
|
|
canvas.drawCircle(
|
|
|
Offset(
|
|
|
- size.width - point.x.toDouble(),
|
|
|
+ point.x.toDouble(),
|
|
|
point.y.toDouble(),
|
|
|
),
|
|
|
2,
|
|
@@ -124,6 +134,16 @@ class _FaceBoundingBoxPainter extends CustomPainter {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// 绘制人脸框
|
|
|
+ void _drawFaceRect(Canvas canvas, Size size, Rect rect) {
|
|
|
+ final paint = Paint()
|
|
|
+ ..color = Colors.green
|
|
|
+ ..strokeWidth = 2
|
|
|
+ ..style = PaintingStyle.stroke;
|
|
|
+
|
|
|
+ canvas.drawRect(rect, paint);
|
|
|
+ }
|
|
|
+
|
|
|
@override
|
|
|
- bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
|
|
|
+ bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
|
|
|
}
|