rainyl / opencv_dart

OpenCV bindings for Dart language and Flutter. Support Asynchronous Now!
https://pub.dev/packages/opencv_dart
Apache License 2.0
136 stars 18 forks source link

Fully support for arguments #180

Closed RajeshMGit closed 3 months ago

RajeshMGit commented 3 months ago

i tried belowcomple example code

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:opencv_dart/opencv_dart.dart' as cv;
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  File? _imageFile;
  File? _processedImageFile;
  final ImagePicker _picker = ImagePicker();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Magic Color Effect Example'),
      ),
      body: Center(
        child: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              _imageFile != null
                  ? Image.file(_imageFile!)
                  : Text('Press the button to pick an image'),
              SizedBox(height: 20),
              _processedImageFile != null
                  ? Image.file(_processedImageFile!)
                  : Container(),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _pickAndProcessImage,
        child: Icon(Icons.image),
      ),
    );
  }

  void _pickAndProcessImage() async {
    final pickedFile = await _picker.pickImage(source: ImageSource.gallery);

    if (pickedFile != null) {
      setState(() {
        _imageFile = File(pickedFile.path);
      });

      final tempDir = await getTemporaryDirectory();
      final outputPath = path.join(tempDir.path, '${DateTime.now().microsecondsSinceEpoch}_processed_image.jpg');

      await OpenCVHelper.processImage(_imageFile!.path, outputPath);

      setState(() {
        _processedImageFile = File(outputPath);
      });
    }
  }
}

class OpenCVHelper {
  static Future<void> processImage(String inputPath, String outputPath) async {
    try {
      cv.Mat img = cv.imread(inputPath);
      cv.Mat imageMatGray = img.convertTo( cv.MatType(-1), alpha: 1.2,beta: -80);
      cv.Mat imageMatBlur = cv.blur(imageMatGray, (21, 21));
      cv.Mat processedImg = cv.Mat.empty();
      cv.divide(imageMatGray, imageMatBlur,dst: processedImg, scale: 254);
      cv.imwrite(outputPath, processedImg);
    } catch (e) {
      print("Error processing image: $e");
    }
  }
}

added below in .yaml file opencv_dart: ^1.1.0+1 screenshot-1722014453010

but it shows blank image. actually code is correct, i done this in opencv java for android, it works fine for that. here it not work.

class OpenCVHelper { static Future processImage(String inputPath, String outputPath) async { try { cv.Mat img = cv.imread(inputPath); cv.Mat imageMatGray = img.convertTo( cv.MatType(-1), alpha: 1.2,beta: -80); cv.Mat imageMatBlur = cv.blur(imageMatGray, (21, 21)); cv.Mat processedImg = cv.Mat.empty(); cv.divide(imageMatGray, imageMatBlur,dst: processedImg, scale: 254); cv.imwrite(outputPath, processedImg); } catch (e) { print("Error processing image: $e"); } } }

In above code imageMatGray can show gray image. That if if you change like below cv.imwrite(outputPath, imageMatGray); it shows gray image imageMatBlur shows blurred image but processedImg which divide output shows blank. i tried both physical device and simulator. Android and ios devices also. Not working.

abdelaziz-mahdy commented 3 months ago

i added more tests and all works correctly, can you share more complete example so we can test the problem more accurately ?

like an example repo with same input.

rainyl commented 3 months ago

Why all of you guys ignored the issue template?

If you want your problems to be solved more quickly and efficiently, PLEASE FOLLOW THE ISSUE TEMPLATE!

abdelaziz-mahdy commented 3 months ago

@RajeshMGit please format your code using three ' before and three ' after, since its not readable

RajeshMGit commented 3 months ago

@RajeshMGit please format your code using three ' before and three ' after, since its not readable

I hope I gave enough details for you to reproduce this issue. Please check and provide a solution.

abdelaziz-mahdy commented 3 months ago

updating your code to show the image in proccess it shows that the gray image is not gray updated code

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:opencv_dart/opencv_dart.dart' as cv;
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  File? _imageFile;
  File? _grayImageFile;
  File? _blurredImageFile;
  File? _dividedImageFile;
  final ImagePicker _picker = ImagePicker();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Magic Color Effect Example'),
      ),
      body: Center(
        child: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              _imageFile != null
                  ? Image.file(_imageFile!)
                  : Text('Press the button to pick an image'),
              SizedBox(height: 20),
              _grayImageFile != null
                  ? Column(
                      children: [
                        Text('Gray Image'),
                        Image.file(_grayImageFile!),
                      ],
                    )
                  : Container(),
              SizedBox(height: 20),
              _blurredImageFile != null
                  ? Column(
                      children: [
                        Text('Blurred Image'),
                        Image.file(_blurredImageFile!),
                      ],
                    )
                  : Container(),
              SizedBox(height: 20),
              _dividedImageFile != null
                  ? Column(
                      children: [
                        Text('Divided Image'),
                        Image.file(_dividedImageFile!),
                      ],
                    )
                  : Container(),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _pickAndProcessImage,
        child: Icon(Icons.image),
      ),
    );
  }

  void _pickAndProcessImage() async {
    final pickedFile = await _picker.pickImage(source: ImageSource.gallery);

    if (pickedFile != null) {
      setState(() {
        _imageFile = File(pickedFile.path);
      });

      final tempDir = await getTemporaryDirectory();
      final grayOutputPath = path.join(tempDir.path,
          '${DateTime.now().microsecondsSinceEpoch}_gray_image.jpg');
      final blurOutputPath = path.join(tempDir.path,
          '${DateTime.now().microsecondsSinceEpoch}_blur_image.jpg');
      final dividedOutputPath = path.join(tempDir.path,
          '${DateTime.now().microsecondsSinceEpoch}_divided_image.jpg');

      await OpenCVHelper.processImage(
          _imageFile!.path, grayOutputPath, blurOutputPath, dividedOutputPath);

      setState(() {
        _grayImageFile = File(grayOutputPath);
        _blurredImageFile = File(blurOutputPath);
        _dividedImageFile = File(dividedOutputPath);
      });
    }
  }
}

class OpenCVHelper {
  static Future<void> processImage(String inputPath, String grayOutputPath,
      String blurOutputPath, String dividedOutputPath) async {
    try {
      cv.Mat img = cv.imread(inputPath);
      cv.Mat imageMatGray =
          img.convertTo(cv.MatType(-1), alpha: 1.2, beta: -80);
      cv.imwrite(grayOutputPath, imageMatGray);

      cv.Mat imageMatBlur = cv.blur(imageMatGray, (21, 21));
      cv.imwrite(blurOutputPath, imageMatBlur);

      cv.Mat processedImg = imageMatGray.divide(imageMatBlur, inplace: false);
      cv.imwrite(dividedOutputPath, processedImg);
    } catch (e) {
      print("Error processing image: $e");
    }
  }
}

output

image image image

replacing these lines results to gray colors but the divided is still fully black, i recommend sending the java code since looks like there is a problem with the logic of the code provided not the package it self

      cv.Mat imageMatGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY);

      // cv.Mat imageMatGray =
      //     img.convertTo(cv.MatType(-1), alpha: 1.2, beta: -80);
rainyl commented 3 months ago

@RajeshMGit It's because the param scale does nothing.

This project was originally started from gocv for it's complete C wrappers, and gocv didn't support the param scale for divide(), I added it here because the APIs in dart were exported from OpenCV C++ documentation, but I do forget this, apologize for the confusion. https://github.com/rainyl/opencv_dart/blob/01a72be62b11d4adcbf7f3934e6d75659bc90675/lib/src/core/core.dart#L419-L434

Will add it in the next release, thanks~

BTW, for now, you can scale the processedImage manually by multiplying it with 254.

final processedImg = cv.divide(imageMatGray, imageMatBlur, scale: 254).multiply<int>(254, inplace: true)
rainyl commented 3 months ago

@abdelaziz-mahdy So maybe we should re-check the arguments of every API and add the unsupported ones in the next stage?

abdelaziz-mahdy commented 3 months ago

@abdelaziz-mahdy So maybe we should re-check the arguments of every API and add the unsupported ones in the next stage?

i get lost by the number of params, if you remember them lets list in a pr and do them all,

this is why i wanted the interface checker since i get lost in the docs :_( but i failed to extract the python interface from opencv

rainyl commented 3 months ago

@abdelaziz-mahdy So maybe we should re-check the arguments of every API and add the unsupported ones in the next stage?

i get lost by the number of params, if you remember them lets list in a pr and do them all,

Actually I didn't remember too. 😵‍💫

this is why i wanted the interface checker since i get lost in the docs :_( but i failed to extract the python interface from opencv

It will be a large project... opencv doesn't have a python documentation, python interfaces are embedded in c++ doc...

Another approach is to extract them from Python source codes via AST, but I am not very familar with AST, more learning needed.

So I think the most easy way for now is manual check, actually dart APIs are copied from c++ doc when I started this project, so we can compare dart args with native calling inside the dart functions, however, I have to admit that it's somehow laborious.

abdelaziz-mahdy commented 3 months ago

if python interface is in the c++ code i think that is much easier, i will look into it again, anyway https://github.com/rainyl/opencv_dart/pull/182 should fix this issue

RajeshMGit commented 3 months ago

@RajeshMGit It's because the param scale does nothing.

This project was originally started from gocv for it's complete C wrappers, and gocv didn't support the param scale for divide(), I added it here because the APIs in dart were exported from OpenCV C++ documentation, but I do forget this, apologize for the confusion.

https://github.com/rainyl/opencv_dart/blob/01a72be62b11d4adcbf7f3934e6d75659bc90675/lib/src/core/core.dart#L419-L434

Will add it in the next release, thanks~

BTW, for now, you can scale the processedImage manually by multiplying it with 254.

final processedImg = cv.divide(imageMatGray, imageMatBlur, scale: 254).multiply<int>(254, inplace: true)

thanks final processedImg = cv.divide(imageMatGray, imageMatBlur, scale: 254).multiply<int>(254, inplace: true) above code works for me..