Flutter的IBM Visual Recognition分类错误

问题描述

我正在尝试拍摄图像并将其发送给IBM Watson,以将其分类为3个定制分类器之一。下面是我的所有代码

import 'dart:io';

import 'package:camera/camera.dart';
import 'package:Flutter/material.dart';
import 'package:Flutter_ibm_watson/Flutter_ibm_watson.dart';
import 'package:ibm_visual_recog_img_file/connection.dart';
import 'package:ourearth2020/screens/Community.dart';
import 'package:path/path.dart';
import 'dart:async';
import 'package:image_picker/image_picker.dart';
import 'package:Flutter_speed_dial/Flutter_speed_dial.dart';
import 'package:path_provider/path_provider.dart';

class VisualPage extends StatefulWidget {
  @override
  _VisualPageState createState() => _VisualPageState();
}

class _VisualPageState extends State<VisualPage> {
  CameraController _controller;
  List cameras;
  String path;
  var galleryImage;

  CameraDescription cameraDescription;

  Future initCamera() async {
    cameras = await availableCameras();
    var frontCamera = cameras.first;

    _controller = CameraController(frontCamera,ResolutionPreset.high);
    try {
      await _controller.initialize();
    } catch (e) {}
    print('Controller Is Init:' + _controller.value.isInitialized.toString());
    displayPreview();
  }
  
  bool displayPreview() {
    if (_controller == null || !_controller.value.isInitialized) {
      return false;
    } else {
      return true;
    }
  }

  Future getimageFromgallery() async {
    var image = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() {
      galleryImage = image;
    });
    print('galLERY IMAGE' + galleryImage.toString());
    return galleryImage;
  }

  @override
  void dispose() {
    // dispose of the controller when the widget is disposed.
    _controller.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    print('Running');
    initCamera();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.white,body: Stack(children: [
          displayPreview()
              ? AspectRatio(
            aspectRatio: MediaQuery.of(context).size.width /
                MediaQuery.of(context).size.height,child: CameraPreview(_controller),)
              : Container(
            child: CircularProgressIndicator(
              valueColor: AlwaysstoppedAnimation<Color>(Colors.yellow),),Positioned(
            top: MediaQuery.of(context).size.height - 120,child: GestureDetector(
                onTap: () async {
                  await getimageFromgallery();
                  Navigator.push(context,MaterialPageRoute(builder: (context) =>
                    displayPicture(image: galleryImage)
                  ));
                },child: Icon(
                  Icons.image,color: Colors.white,size: 60,)),Positioned(
              top: MediaQuery.of(context).size.height - 120,left: MediaQuery.of(context).size.width / 2.2,child: GestureDetector(
                  behavior: HitTestBehavior.translucent,child: Container(
                      child: Icon(
                        Icons.camera,onTap: () async {
                    final path = (await getTemporaryDirectory()).path +
                        '${DateTime.Now()}.png';
                    try {
                      await _controller.takePicture(path);
                      Navigator.push(
                          context,MaterialPageRoute(
                              builder: (context) =>
                                  displayPicture(imagePath: path)));
                    } catch (e) {
                      print('EEEE' + e);
                    }
                  }))
        ]));
  }
}

class displayPicture extends StatelessWidget {
  String imagePath;
  File image;
  String _text;
  // File file = File(imagePath)
  displayPicture({this.imagePath,this.image});

   visualImageClassifier(File image) async{
      IamOptions options = await IamOptions(iamApiKey: "NRDjngCby2d-pSHOPyWQJxhuB6vOY2uOTCX6KV2BCfwB",url: "https://api.us-south.visual-recognition.watson.cloud.ibm.com/instances/ef286f4e-84c7-44e0-b63d-a6a49a142a30").build();
      VisualRecognition visualRecognition = new VisualRecognition(iamOptions: options,language: Language.ENGLISH); // Language.ENGLISH is language response
      ClassifiedImages classifiedImages = await visualRecognition.classifyImageFile(image.path);
      print(classifiedImages.getimages()[0].getClassifiers()[0]
          .getClasses()[0]
          .className);
      // print("${image.toString()}");
     // print('ACCESS'+options.accesstoken);
      //print(options);
      //print("${image.path}");
      //print('CLASSIFICATION'+classifiedImages.customClasses.toString());    // StreamBuilder(
    //     stream: StreamMyClassifier(
    //         image,//         'NRDjngCby2d-pSHOPyWQJxhuB6vOY2uOTCX6KV2BCfwB','CompostxLandfillxRecycle_2056123069'),//     builder: (context,snapshot) {
    //       if (snapshot.hasData) {
    //         _text = snapshot.data;
    //         print(_text);
    //       }
    //       else {
    //  print('NO DATA AVAILABLE');
    //       }
    //
    //     }
    // );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(body:Stack(children:[Center(child:image==null?Image.file(File(imagePath)):Image.file(image)),Positioned(
      top: MediaQuery.of(context).size.height/2,child: FloatingActionButton(onpressed:() async{
        await visualImageClassifier(image==null?File(imagePath):image);
      },child:Icon(Icons.arrow_right)),)]));

  }
}

该图像已成功显示在我的屏幕上,但是一旦我通过visualRecognition.classifyImageFile(....);发送该图像,就会出现一条错误消息,说我无法使用image,因为它仅支持String。我将其转换为String,但它给了我下面的错误

[ERROR:Flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: filesystemexception: Cannot retrieve length of file,path = 'File: '/data/user/0/com.example.ourearth2020/cache2020-09-17 18:50:16.530957.png'' (OS Error: No such file or directory,errno = 2)
E/Flutter (17606): #0      _File.length.<anonymous closure> (dart:io/file_impl.dart:366:9)
E/Flutter (17606): #1      _rootRunUnary (dart:async/zone.dart:1198:47)
E/Flutter (17606): #2      _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/Flutter (17606): #3      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
E/Flutter (17606): #4      Future._propagatetoListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
E/Flutter (17606): #5      Future._propagatetoListeners (dart:async/future_impl.dart:725:32)
E/Flutter (17606): #6      Future._completeWithValue (dart:async/future_impl.dart:529:5)
E/Flutter (17606): #7      Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:567:7)
E/Flutter (17606): #8      _rootRun (dart:async/zone.dart:1190:13)
E/Flutter (17606): #9      _CustomZone.run (dart:async/zone.dart:1093:19)
E/Flutter (17606): #10     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/Flutter (17606): #11     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
E/Flutter (17606): #12     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
E/Flutter (17606): #13     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
E/Flutter (17606): 

我有一些问题:我可以使用它获得置信度分数吗?上一次我尝试使用这些语句对图像进行分类时,它使用了常规分类器(如果我输入了摩天大楼的图像,它告诉了摩天大楼),那么如何使用3个分类器对其进行分类

顺便说一句,我已经设置了IBM Cloud,并且它可以正常运行。我在pub.dev中找到的库位于https://pub.dev/packages/Flutter_ibm_watson

getimages()方法

EDIT 错误代码

[ERROR:Flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: NoSuchMethodError: The method 'getimages' was called on null.
E/Flutter (31403): Receiver: null
E/Flutter (31403): Tried calling: getimages()
E/Flutter (31403): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
E/Flutter (31403): #1      displayPicture.visualImageClassifier (package:ourearth2020/screens/VisualPage.dart:147:30)
E/Flutter (31403): <asynchronous suspension>
E/Flutter (31403): #2      displayPicture.build.<anonymous closure> (package:ourearth2020/screens/VisualPage.dart:177:15)
E/Flutter (31403): #3      _InkResponseState._handleTap (package:Flutter/src/material/ink_well.dart:992:19)
E/Flutter (31403): #4      _InkResponseState.build.<anonymous closure> (package:Flutter/src/material/ink_well.dart:1098:38)
E/Flutter (31403): #5      GestureRecognizer.invokeCallback (package:Flutter/src/gestures/recognizer.dart:184:24)
E/Flutter (31403): #6      TapGestureRecognizer.handleTapUp (package:Flutter/src/gestures/tap.dart:524:11)
E/Flutter (31403): #7      BaseTapGestureRecognizer._checkUp (package:Flutter/src/gestures/tap.dart:284:5)
E/Flutter (31403): #8      BaseTapGestureRecognizer.handlePrimaryPointer (package:Flutter/src/gestures/tap.dart:219:7)
E/Flutter (31403): #9      PrimaryPointerGestureRecognizer.handleEvent (package:Flutter/src/gestures/recognizer.dart:477:9)
E/Flutter (31403): #10     PointerRouter._dispatch (package:Flutter/src/gestures/pointer_router.dart:78:12)
E/Flutter (31403): #11     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:Flutter/src/gestures/pointer_router.dart:124:9)
E/Flutter (31403): #12     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:377:8)
E/Flutter (31403): #13     PointerRouter._dispatchEventToRoutes (package:Flutter/src/gestures/pointer_router.dart:122:18)
E/Flutter (31403): #14     PointerRouter.route (package:Flutter/src/gestures/pointer_router.dart:108:7)
E/Flutter (31403): #15     GestureBinding.handleEvent (package:Flutter/src/gestures/binding.dart:220:19)
E/Flutter (31403): #16     GestureBinding.dispatchEvent (package:Flutter/src/gestures/binding.dart:200:22)
E/Flutter (31403): #17     GestureBinding._handlePointerEvent (package:Flutter/src/gestures/binding.dart:158:7)
E/Flutter (31403): #18     GestureBinding._flushPointerEventQueue (package:Flutter/src/gestures/binding.dart:104:7)
E/Flutter (31403): #19     GestureBinding._handlePointerDataPacket (package:Flutter/src/gestures/binding.dart:88:7)
E/Flutter (31403): #20     _rootRunUnary (dart:async/zone.dart:1206:13)
E/Flutter (31403): #21     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/Flutter (31403): #22     _CustomZone.runUnaryguarded (dart:async/zone.dart:1005:7)
E/Flutter (31403): #23     _invoke1 (dart:ui/hooks.dart:283:10)
E/Flutter (31403): #24     _dispatchPointerDataPacket (dart:ui/hooks.dart:192:5)
E/Flutter (31403): 

解决方法

您可以在下面复制过去的完整运行代码
您可以在下面的工作演示中看到置信度得分
请将image.toString()更改为image.path,因为imageFile
来自

ClassifiedImages classifiedImages = await visualRecognition.classifyImageFile(image.toString());

ClassifiedImages classifiedImages = await visualRecognition.classifyImageFile(image.path);

工作演示

enter image description here

CameraPreview的工作演示2

I/flutter (31132): living room

enter image description here

完整代码

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'dart:io';

import 'package:flutter_ibm_watson/flutter_ibm_watson.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';

class VisualPage extends StatefulWidget {
  @override
  _VisualPageState createState() => _VisualPageState();
}

class _VisualPageState extends State<VisualPage> {
  CameraController _controller;
  List cameras;
  String path;
  var galleryImage;

  CameraDescription cameraDescription;

  Future initCamera() async {
    cameras = await availableCameras();
    var frontCamera = cameras.first;

    _controller = CameraController(frontCamera,ResolutionPreset.high);
    try {
      await _controller.initialize();
    } catch (e) {}
    print('Controller Is Init:' + _controller.value.isInitialized.toString());
    displayPreview();
    setState(() {});
  }

  bool displayPreview() {
    if (_controller == null || !_controller.value.isInitialized) {
      return false;
    } else {
      return true;
    }
  }

  Future getImageFromGallery() async {
    var image = await ImagePicker.pickImage(source: ImageSource.gallery);
    setState(() {
      galleryImage = image;
    });
    print('GALLERY IMAGE' + galleryImage.toString());
    return galleryImage;
  }

  @override
  void dispose() {
    // Dispose of the controller when the widget is disposed.
    _controller.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    print('Running');

    initCamera();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        backgroundColor: Colors.white,body: Stack(children: [
          displayPreview()
              ? AspectRatio(
                  aspectRatio: MediaQuery.of(context).size.width /
                      MediaQuery.of(context).size.height,child: CameraPreview(_controller),)
              : Container(
                  child: CircularProgressIndicator(
                    valueColor: AlwaysStoppedAnimation<Color>(Colors.yellow),),Positioned(
            top: MediaQuery.of(context).size.height - 120,child: GestureDetector(
                onTap: () async {
                  await getImageFromGallery();
                  Navigator.push(
                      context,MaterialPageRoute(
                          builder: (context) =>
                              DisplayPicture(image: galleryImage)));
                },child: Icon(
                  Icons.image,color: Colors.white,size: 60,)),Positioned(
              top: MediaQuery.of(context).size.height - 120,left: MediaQuery.of(context).size.width / 2.2,child: GestureDetector(
                  behavior: HitTestBehavior.translucent,child: Container(
                      child: Icon(
                    Icons.camera,onTap: () async {
                    final path = (await getTemporaryDirectory()).path +
                        '${DateTime.now()}.png';
                    try {
                      await _controller.takePicture(path);
                      Navigator.push(
                          context,MaterialPageRoute(
                              builder: (context) =>
                                  DisplayPicture(imagePath: path)));
                    } catch (e) {
                      print('EEEE' + e);
                    }
                  }))
        ]));
  }
}

class DisplayPicture extends StatelessWidget {
  String imagePath;
  File image;
  String _text;
  // File file = File(imagePath)
  DisplayPicture({this.imagePath,this.image});

  visualImageClassifier(File image) async {
    IamOptions options = await IamOptions(
            iamApiKey: "NRDjngCby2d-pSHOPyWQJxhuB6vOY2uOTCX6KV2BCfwB",url:
                "https://api.us-south.visual-recognition.watson.cloud.ibm.com/instances/ef286f4e-84c7-44e0-b63d-a6a49a142a30")
        .build();
    VisualRecognition visualRecognition = new VisualRecognition(
        iamOptions: options,language: Language.ENGLISH); // Language.ENGLISH is language response
    ClassifiedImages classifiedImages =
        await visualRecognition.classifyImageFile(image.path);
    print(classifiedImages
        .getImages()[0]
        .getClassifiers()[0]
        .getClasses()[0]
        .className);
    // print("${image.toString()}");
    // print('ACCESS'+options.accessToken);
    //print(options);
    //print("${image.path}");
    //print('CLASSIFICATION'+classifiedImages.customClasses.toString());    // StreamBuilder(
    //     stream: StreamMyClassifier(
    //         image,//         'NRDjngCby2d-pSHOPyWQJxhuB6vOY2uOTCX6KV2BCfwB','CompostxLandfillxRecycle_2056123069'),//     builder: (context,snapshot) {
    //       if (snapshot.hasData) {
    //         _text = snapshot.data;
    //         print(_text);
    //       }
    //       else {
    //  print('NO DATA AVAILABLE');
    //       }
    //
    //     }
    // );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Stack(children: [
      Center(
          child:
              image == null ? Image.file(File(imagePath)) : Image.file(image)),Positioned(
        top: MediaQuery.of(context).size.height / 2,child: FloatingActionButton(
            onPressed: () async {
              await visualImageClassifier(
                  image == null ? File(imagePath) : image);
            },child: Icon(Icons.arrow_right)),)
    ]));
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',theme: ThemeData(
        primarySwatch: Colors.blue,visualDensity: VisualDensity.adaptivePlatformDensity,home: VisualPage(),);
  }
}