📜  Flutter的掩码检测应用

📅  最后修改于: 2021-09-02 05:07:18             🧑  作者: Mango

如今在Covid的情况下,戴口罩保护自己和他人非常重要。所以这个应用程序有助于检测这个人是否戴过口罩。在这个应用程序中,掩码检测是在 TensorFlow Lite 的帮助下完成的。

按照步骤在我们的Flutter应用程序中实现掩码检测

  • 将依赖项添加到pubspec.yaml文件。
  • 将依赖项导入到 main.js 中。dart文件

第 1 步:首先在您的 pubspec.yaml 文件中添加以下依赖项

pubspec.yaml文件中添加给定的依赖

Dart
dependencies:
   
  cupertino_icons: ^1.0.2
  image_picker: ^0.7.4
  tflite:
  google_fonts:


Dart
void main() {
  runApp(MyApp());
}
  
class MyApp extends StatelessWidget {
    
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
      
    // Material App
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
      brightness: Brightness.dark,
        primaryColor: Color(0xff01AEBC),
      ),
        
      // Main Screen in our app
      home: HomePage(),
    );
  }
}


Dart
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}
  
class _HomePageState extends State {
    
  // Variables Declared
  bool _loading = true;
  File _image;
  final imagePicker = ImagePicker();
  List _predictions = [];
  
  // Methods to pick the image  from Camera and Gallery
  Future loadImageGallery() async {
    final image = await imagePicker.getImage(source: ImageSource.gallery);
    detectImage(image);
  }
  
  Future loadImageCamera() async {
    final image = await imagePicker.getImage(source: ImageSource.camera);
    detectImage(image);
  }


Dart
//Initialize the state 
@override
  void initState() {
    // TODO: implement initState
    super.initState();
    loadModel();
  }
  
  // Added extracted files in loadModel() function
  loadModel() async{
    Tflite.close();
    await Tflite.loadModel(model: 'assets/model_unquant.tflite',
                           labels: 'assets/labels.txt');
  }
  
 // Created detectImage() for detecting the image
 Future detectImage(image) async {
    var prediction = await Tflite.runModelOnImage(
        path: image.path,
        numResults: 2,
        threshold: 0.6,
        imageMean: 127.5,
        imageStd: 127.5,
    );
    setState(() {
      _loading = false;
      if (image != null) {
        _image = File(image.path);
        _predictions = prediction;
      } else {
        print('No image selected.');
      }
    });
  }
  
  // Ended the function
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }


Dart
@override
  Widget build(BuildContext context) {
    return Scaffold(
        
      // Appbar declared
      appBar: AppBar(
        title: Text('Mask Detection',
        style: GoogleFonts.robotoCondensed(),
        ),
      ),
      body: SingleChildScrollView(
          
        // Column containing images and buttons
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
              
            // Image will display here
            _loading == false ? Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                child: Column(
                  children: [
                    Container(
                      height: 280,
                      width: 220,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(25),
                      ),
                      child: ClipRRect(
                          borderRadius: BorderRadius.circular(25),
                          child: Image.file(_image)),
                    ),
                    SizedBox(height: 10),
  
                    Text(_predictions[0]['label'].toString().substring(2),
                      style: GoogleFonts.robotoCondensed(
                        fontSize: 20,
                      ),
                    ),
                    SizedBox(height: 10),
                    // Text('Safer: '+"${(_predictions[0]
                    // ['confidence']*100).toString()}%"),
                  ],
                ),
              ),
            ):Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                height: 300,
                width: 250,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(15),
                  color: Colors.grey,
                ),
                child: Center(child: Text('Image Appears here')),
              ),
            ),
            SizedBox(height: 10),
              
            // Capture Image from Camera
            Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                height: 50,
                width: double.infinity,
                child: RaisedButton(
                    onPressed: (){
                        
                     // Methods we created above
                      loadImageCamera();
                    },
                child: Text('Capture Image'),
                  color: Color(0xff01AEBC),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  ),
                ),
              ),
            ),
            SizedBox(height: 10),
              
            // Capture Image from Gallery
            Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                height: 50,
                width: double.infinity,
                child: RaisedButton(
                  onPressed: (){
                      
                    // Methods we created above
                    loadImageGallery();
                  },
                  child: Text('Pick Image from Gallery'),
                  color: Color(0xff01AEBC),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );


Dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:image_picker/image_picker.dart';
import 'package:tflite/tflite.dart';
  
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}
  
class _HomePageState extends State {
  bool _loading = true;
  File _image;
  final imagePicker = ImagePicker();
  List _predictions = [];
    
  // For picking image from Gallery
  Future loadImageGallery() async {
    final image = await imagePicker.getImage(source: ImageSource.gallery);
    detectImage(image);
  }
    
  // For picking image from Camera
  Future loadImageCamera() async {
    final image = await imagePicker.getImage(source: ImageSource.camera);
    detectImage(image);
  }
  
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    loadModel();
  }
    
  // LoadModel() for connection app with TensorFlow Lite
  loadModel() async{
    Tflite.close();
    await Tflite.loadModel(model: 'assets/model_unquant.tflite',
                           labels: 'assets/labels.txt');
  }
    
 // Method for Image detection
 Future detectImage(image) async {
    var prediction = await Tflite.runModelOnImage(
        path: image.path,
        numResults: 2,
        threshold: 0.6,
        imageMean: 127.5,
        imageStd: 127.5,
    );
    setState(() {
      _loading = false;
      if (image != null) {
        _image = File(image.path);
        _predictions = prediction;
      } else {
        print('No image selected.');
      }
    });
    // setState(() {
    //   _loading = false;
    //   _predictions = prediction;
    // });
  }
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }
  
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // Appbar displayed here
      appBar: AppBar(
        title: Text('Mask Detection',
        style: GoogleFonts.robotoCondensed(),
        ),
      ),
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
              
             // Image will display here
            _loading == false ? Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                child: Column(
                  children: [
                    Container(
                      height: 280,
                      width: 220,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(25),
                      ),
                      child: ClipRRect(
                          borderRadius: BorderRadius.circular(25),
                          child: Image.file(_image)),
                    ),
                    SizedBox(height: 10),
  
                    Text(_predictions[0]['label'].toString().substring(2),
                      style: GoogleFonts.robotoCondensed(
                        fontSize: 20,
                      ),
                    ),
                    SizedBox(height: 10),
                    // Text('Safer: '+"${(_predictions[0]['confidence']*100).toString()}%"),
                  ],
                ),
              ),
            ):Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                height: 300,
                width: 250,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(15),
                  color: Colors.grey,
                ),
                child: Center(child: Text('Image Appears here')),
              ),
            ),
            SizedBox(height: 10),
            // Button for taking Image from Camera
            Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                height: 50,
                width: double.infinity,
                child: RaisedButton(
                    onPressed: (){
                      loadImageCamera();
                    },
                child: Text('Capture Image'),
                  color: Color(0xff01AEBC),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  ),
                ),
              ),
            ),
            SizedBox(height: 10),
            // Button for taking Image from Gallery
            Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                height: 50,
                width: double.infinity,
                child: RaisedButton(
                  onPressed: (){
                    loadImageGallery();
                  },
                  child: Text('Pick Image from Gallery'),
                  color: Color(0xff01AEBC),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}


第 2 步:现在导航到 main。 dart() 文件并返回 Material App()。

首先,我们在 main函数的runApp 中声明了MyApp() 。然后我们为MyApp创建了StatelessWidget ,其中我们返回了MaterialApp()。在这种MaterialApp(),我们已经给我们的应用程序的标题,然后宣布我们的应用程序的主题,primaryColor为蓝色。然后我们在主页中给出了我们的第一个屏幕或滑块应用程序: HomePage()

Dart

void main() {
  runApp(MyApp());
}
  
class MyApp extends StatelessWidget {
    
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
      
    // Material App
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
      brightness: Brightness.dark,
        primaryColor: Color(0xff01AEBC),
      ),
        
      // Main Screen in our app
      home: HomePage(),
    );
  }
}

第 3 步:现在为 HomePage() 类声明 StatefulWidget()。

在这个StatefulWidget() 中,我们在 state函数下声明了各种变量。之后,我们为loadImageGallery()loadImageCamera()声明了方法这些方法用于的帮助下选择画廊和摄像机的图像 我们导入的image_picker 库

Dart

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}
  
class _HomePageState extends State {
    
  // Variables Declared
  bool _loading = true;
  File _image;
  final imagePicker = ImagePicker();
  List _predictions = [];
  
  // Methods to pick the image  from Camera and Gallery
  Future loadImageGallery() async {
    final image = await imagePicker.getImage(source: ImageSource.gallery);
    detectImage(image);
  }
  
  Future loadImageCamera() async {
    final image = await imagePicker.getImage(source: ImageSource.camera);
    detectImage(image);
  }

第 4 步:现在继续使用 Google Teachable Machine。

现在开始使用Google Teachable Machine 。您可以在哪里训练用于掩码检测的模型。现在单击图像项目。在这里,您必须创建两个类,一个用于遮罩,另一个用于无遮罩。现在在面具类中单击网络摄像头以从各个角度记录您的面具。以同样的方式,您将从所有角度在无面具类中记录您的无面具脸。现在点击训练模型

完成后,您将单击“导出模型”

步骤1:

第2步:

第 3 步:

然后点击Tensorflow Lite并在其中选择Floating point然后点击Download my model 。现在下载模型后提取文件。现在将提取的文件添加到pubspec.yaml文件中的资产文件夹。

第 5 步:现在添加以下代码行以将您的模型导入您的应用程序。

现在我们已经创建了loadModel()我们在这个方法中添加了我们下载的文件的提取文件。我们已经在initState()中初始化了loadModel()。之后,我们创建了用于检测图像的detectImage() 之后,我们设置了更新图像的状态。

我们已经使用dispose()结束了该函数。

Dart

//Initialize the state 
@override
  void initState() {
    // TODO: implement initState
    super.initState();
    loadModel();
  }
  
  // Added extracted files in loadModel() function
  loadModel() async{
    Tflite.close();
    await Tflite.loadModel(model: 'assets/model_unquant.tflite',
                           labels: 'assets/labels.txt');
  }
  
 // Created detectImage() for detecting the image
 Future detectImage(image) async {
    var prediction = await Tflite.runModelOnImage(
        path: image.path,
        numResults: 2,
        threshold: 0.6,
        imageMean: 127.5,
        imageStd: 127.5,
    );
    setState(() {
      _loading = false;
      if (image != null) {
        _image = File(image.path);
        _predictions = prediction;
      } else {
        print('No image selected.');
      }
    });
  }
  
  // Ended the function
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

第 6 步:之后,我们给出了应用程序的 UI。

在这个StateFulWidget() 中,我们已经声明了Scaffold() 。我们在这个应用栏中声明了Appbar() ,我们在Text Widget 中给出了我们的应用程序的标题在 body 部分的appbar之后,我们已经声明了Column() ,其中图像和按钮将出现在另一个下方。当我们点击捕获图像按钮时,设备的摄像头将打开,您必须捕获将检测掩码的图像。

以同样的方式单击Pick Image from Gallery 。您的文件管理器将打开,您可以从中选择用于检测蒙版的图像。

Dart

@override
  Widget build(BuildContext context) {
    return Scaffold(
        
      // Appbar declared
      appBar: AppBar(
        title: Text('Mask Detection',
        style: GoogleFonts.robotoCondensed(),
        ),
      ),
      body: SingleChildScrollView(
          
        // Column containing images and buttons
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
              
            // Image will display here
            _loading == false ? Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                child: Column(
                  children: [
                    Container(
                      height: 280,
                      width: 220,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(25),
                      ),
                      child: ClipRRect(
                          borderRadius: BorderRadius.circular(25),
                          child: Image.file(_image)),
                    ),
                    SizedBox(height: 10),
  
                    Text(_predictions[0]['label'].toString().substring(2),
                      style: GoogleFonts.robotoCondensed(
                        fontSize: 20,
                      ),
                    ),
                    SizedBox(height: 10),
                    // Text('Safer: '+"${(_predictions[0]
                    // ['confidence']*100).toString()}%"),
                  ],
                ),
              ),
            ):Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                height: 300,
                width: 250,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(15),
                  color: Colors.grey,
                ),
                child: Center(child: Text('Image Appears here')),
              ),
            ),
            SizedBox(height: 10),
              
            // Capture Image from Camera
            Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                height: 50,
                width: double.infinity,
                child: RaisedButton(
                    onPressed: (){
                        
                     // Methods we created above
                      loadImageCamera();
                    },
                child: Text('Capture Image'),
                  color: Color(0xff01AEBC),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  ),
                ),
              ),
            ),
            SizedBox(height: 10),
              
            // Capture Image from Gallery
            Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                height: 50,
                width: double.infinity,
                child: RaisedButton(
                  onPressed: (){
                      
                    // Methods we created above
                    loadImageGallery();
                  },
                  child: Text('Pick Image from Gallery'),
                  color: Color(0xff01AEBC),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );

面具检测应用程序的完整代码:

Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:image_picker/image_picker.dart';
import 'package:tflite/tflite.dart';
  
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}
  
class _HomePageState extends State {
  bool _loading = true;
  File _image;
  final imagePicker = ImagePicker();
  List _predictions = [];
    
  // For picking image from Gallery
  Future loadImageGallery() async {
    final image = await imagePicker.getImage(source: ImageSource.gallery);
    detectImage(image);
  }
    
  // For picking image from Camera
  Future loadImageCamera() async {
    final image = await imagePicker.getImage(source: ImageSource.camera);
    detectImage(image);
  }
  
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    loadModel();
  }
    
  // LoadModel() for connection app with TensorFlow Lite
  loadModel() async{
    Tflite.close();
    await Tflite.loadModel(model: 'assets/model_unquant.tflite',
                           labels: 'assets/labels.txt');
  }
    
 // Method for Image detection
 Future detectImage(image) async {
    var prediction = await Tflite.runModelOnImage(
        path: image.path,
        numResults: 2,
        threshold: 0.6,
        imageMean: 127.5,
        imageStd: 127.5,
    );
    setState(() {
      _loading = false;
      if (image != null) {
        _image = File(image.path);
        _predictions = prediction;
      } else {
        print('No image selected.');
      }
    });
    // setState(() {
    //   _loading = false;
    //   _predictions = prediction;
    // });
  }
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }
  
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // Appbar displayed here
      appBar: AppBar(
        title: Text('Mask Detection',
        style: GoogleFonts.robotoCondensed(),
        ),
      ),
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
              
             // Image will display here
            _loading == false ? Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                child: Column(
                  children: [
                    Container(
                      height: 280,
                      width: 220,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(25),
                      ),
                      child: ClipRRect(
                          borderRadius: BorderRadius.circular(25),
                          child: Image.file(_image)),
                    ),
                    SizedBox(height: 10),
  
                    Text(_predictions[0]['label'].toString().substring(2),
                      style: GoogleFonts.robotoCondensed(
                        fontSize: 20,
                      ),
                    ),
                    SizedBox(height: 10),
                    // Text('Safer: '+"${(_predictions[0]['confidence']*100).toString()}%"),
                  ],
                ),
              ),
            ):Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                height: 300,
                width: 250,
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(15),
                  color: Colors.grey,
                ),
                child: Center(child: Text('Image Appears here')),
              ),
            ),
            SizedBox(height: 10),
            // Button for taking Image from Camera
            Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                height: 50,
                width: double.infinity,
                child: RaisedButton(
                    onPressed: (){
                      loadImageCamera();
                    },
                child: Text('Capture Image'),
                  color: Color(0xff01AEBC),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  ),
                ),
              ),
            ),
            SizedBox(height: 10),
            // Button for taking Image from Gallery
            Padding(
              padding: const EdgeInsets.all(10.0),
              child: Container(
                height: 50,
                width: double.infinity,
                child: RaisedButton(
                  onPressed: (){
                    loadImageGallery();
                  },
                  child: Text('Pick Image from Gallery'),
                  color: Color(0xff01AEBC),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(15),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

输出:

想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!