rainyl / opencv_dart

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

How to "getPerspectiveTransform" and "warpPerspective"? #61

Closed tekink closed 3 months ago

tekink commented 4 months ago

Question

I want to warp a picture by taken camera. I detect rectangle but i can't find corners of rectangle.

  Future<Uint8List> heavyTask(Uint8List buffer) async {
    final ret = Isolate.run(() {
      final im = cv.imdecode(Uint8List.fromList(buffer), cv.IMREAD_COLOR);
      late cv.Mat gray, blur,canny,contour;
      cv.VecVecPoint point;
      gray = cv.cvtColor(im, cv.COLOR_BGR2GRAY);
      blur = cv.gaussianBlur(im, (5, 5), 1, sigmaY: 2);
      canny = cv.canny(blur, 0, 50);
      (point, contour) = cv.findContours(canny, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE);
      int maxval = 0;
      cv.VecPoint max = point.first;
      for (var element in point) {
        if (element.length > maxval) {
          maxval = element.length;
          max = element;
        }
      }

      cv.Mat draw = cv.drawContours(im, point, -1, cv.Scalar.blue);
      cv.Mat tra = cv.getPerspectiveTransform(
          max,
          cv.VecPoint.fromList([
            cv.Point(0, 0),
            cv.Point(0, 100),
            cv.Point(100, 0),
            cv.Point(100, 100),
          ]));
      return cv.imencode(cv.ImageFormat.png.ext, draw);
    });
    return ret;
  }

It can detect rectangle and draw contour Screenshot_1716215973

I got error at cv.getPerspectiveTransform

Reloaded 1 of 797 libraries in 685ms (compile: 17 ms, reload: 168 ms, reassemble: 257 ms). D/EGL_emulation( 7180): app_time_stats: avg=2339.90ms min=6.37ms max=55623.45ms count=24 D/EGL_emulation( 7180): app_time_stats: avg=1311.41ms min=1311.41ms max=1311.41ms count=1 E/cv::error()( 7180): OpenCV(4.9.0) Error: Assertion failed (src.checkVector(2, CV_32F) == 4 && dst.checkVector(2, CV_32F) == 4) in getPerspectiveTransform, file /home/runner/work/opencv.full/opencv.full/build/opencv/modules/imgproc/src/imgwarp.cpp, line 3547 E/flutter ( 7180): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: CvException(code: ErrorCode(-215), err: , msg:OpenCV(4.9.0) /home/runner/work/opencv.full/opencv.full/build/opencv/modules/imgproc/src/imgwarp.cpp:3547: error: (-215:Assertion failed) src.checkVector(2, CV_32F) == 4 && dst.checkVector(2, CV_32F) == 4 in function 'getPerspectiveTransform' E/flutter ( 7180): ) in getPerspectiveTransform of file /home/runner/work/opencv.full/opencv.full/build/opencv/modules/imgproc/src/imgwarp.cpp:3547 E/flutter ( 7180): #0 cvRun (package:opencv_dart/src/core/base.dart:69:5) E/flutter ( 7180): #1 getPerspectiveTransform. (package:opencv_dart/src/imgproc/imgproc.dart:1261:5) E/flutter ( 7180): #2 cvRunArena (package:opencv_dart/src/core/base.dart:84:31) E/flutter ( 7180): #3 getPerspectiveTransform (package:opencv_dart/src/imgproc/imgproc.dart:1259:10) E/flutter ( 7180): #4 _MyAppState.heavyTask. (package:demo/main.dart:54:23) E/flutter ( 7180): #5 _RemoteRunner._run (dart:isolate:1090:47) E/flutter ( 7180): #6 _RemoteRunner._remoteExecute (dart:isolate:1084:12) E/flutter ( 7180): #7 _delayEntrypointInvocation. (dart:isolate-patch/isolate_patch.dart:300:17) E/flutter ( 7180): #8 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12) E/flutter ( 7180):

rainyl commented 4 months ago

check the length of max

thanhle7 commented 4 months ago

Question

I want to warp a picture by taken camera. I detect rectangle but i can't find corners of rectangle.

  Future<Uint8List> heavyTask(Uint8List buffer) async {
    final ret = Isolate.run(() {
      final im = cv.imdecode(Uint8List.fromList(buffer), cv.IMREAD_COLOR);
      late cv.Mat gray, blur,canny,contour;
      cv.VecVecPoint point;
      gray = cv.cvtColor(im, cv.COLOR_BGR2GRAY);
      blur = cv.gaussianBlur(im, (5, 5), 1, sigmaY: 2);
      canny = cv.canny(blur, 0, 50);
      (point, contour) = cv.findContours(canny, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE);
      int maxval = 0;
      cv.VecPoint max = point.first;
      for (var element in point) {
        if (element.length > maxval) {
          maxval = element.length;
          max = element;
        }
      }

      cv.Mat draw = cv.drawContours(im, point, -1, cv.Scalar.blue);
      cv.Mat tra = cv.getPerspectiveTransform(
          max,
          cv.VecPoint.fromList([
            cv.Point(0, 0),
            cv.Point(0, 100),
            cv.Point(100, 0),
            cv.Point(100, 100),
          ]));
      return cv.imencode(cv.ImageFormat.png.ext, draw);
    });
    return ret;
  }

It can detect rectangle and draw contour Screenshot_1716215973

I got error at cv.getPerspectiveTransform

Reloaded 1 of 797 libraries in 685ms (compile: 17 ms, reload: 168 ms, reassemble: 257 ms). D/EGL_emulation( 7180): app_time_stats: avg=2339.90ms min=6.37ms max=55623.45ms count=24 D/EGL_emulation( 7180): app_time_stats: avg=1311.41ms min=1311.41ms max=1311.41ms count=1 E/cv::error()( 7180): OpenCV(4.9.0) Error: Assertion failed (src.checkVector(2, CV_32F) == 4 && dst.checkVector(2, CV_32F) == 4) in getPerspectiveTransform, file /home/runner/work/opencv.full/opencv.full/build/opencv/modules/imgproc/src/imgwarp.cpp, line 3547 E/flutter ( 7180): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: CvException(code: ErrorCode(-215), err: , msg:OpenCV(4.9.0) /home/runner/work/opencv.full/opencv.full/build/opencv/modules/imgproc/src/imgwarp.cpp:3547: error: (-215:Assertion failed) src.checkVector(2, CV_32F) == 4 && dst.checkVector(2, CV_32F) == 4 in function 'getPerspectiveTransform' E/flutter ( 7180): ) in getPerspectiveTransform of file /home/runner/work/opencv.full/opencv.full/build/opencv/modules/imgproc/src/imgwarp.cpp:3547 E/flutter ( 7180): #0 cvRun (package:opencv_dart/src/core/base.dart:69:5) E/flutter ( 7180): #1 getPerspectiveTransform. (package:opencv_dart/src/imgproc/imgproc.dart:1261:5) E/flutter ( 7180): #2 cvRunArena (package:opencv_dart/src/core/base.dart:84:31) E/flutter ( 7180): #3 getPerspectiveTransform (package:opencv_dart/src/imgproc/imgproc.dart:1259:10) E/flutter ( 7180): #4 _MyAppState.heavyTask. (package:demo/main.dart:54:23) E/flutter ( 7180): #5 _RemoteRunner._run (dart:isolate:1090:47) E/flutter ( 7180): #6 _RemoteRunner._remoteExecute (dart:isolate:1084:12) E/flutter ( 7180): #7 _delayEntrypointInvocation. (dart:isolate-patch/isolate_patch.dart:300:17) E/flutter ( 7180): #8 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12) E/flutter ( 7180):

I addressed the same problem by using bookmarks :)

thanhle7 commented 4 months ago

check the length of max

Thank you for your wonderful work!

rainyl commented 3 months ago

https://docs.opencv.org/4.x/da/d54/group__imgproc__transform.html#ga20f62aa3235d869c9956436c870893ae

According to the documentation of opencv, the src and dst must be 4-points, that's why it complains Assertion failed (src.checkVector(2, CV_32F) == 4 && dst.checkVector(2, CV_32F) == 4) in getPerspectiveTransform, I tested your code and the max is not a 4-point Vector, so please check your algorithm.

Closed.

gustavovisentini commented 2 months ago

its possible order by size of contourArea in this vector VecVecPoint? My code in c++

std::vector<int> pointsVector;
    for(int i=0;i<contours.size();i++){
        pointsVector.push_back(contourArea(contours[i]));
    }
    //std::cout<<"\n Vetor Ordenado:\n\n";
    std::sort(pointsVector.begin(), pointsVector.end());
    for(int i=0;i<pointsVector.size();i++){
        //std::cout<<"\n"<<pointsVector[i];
    }

    int areaTotalGotas=0;
    for(int i=0;i<pointsVector.size();i++){
        areaTotalGotas=areaTotalGotas+pointsVector[i];
    }

    //std::cout<<"\nVolume: "<<areaTotalGotas<<"\n\n";
    int dmvPre = areaTotalGotas/2;
    int dmvAux=0;
    int dmv=0;
    int pos=0;
    for(int i=0;i<=pointsVector.size();i++){
        if (dmvAux<dmvPre){
            dmvAux=dmvAux+pointsVector[i];
            pos = i;
        }
    }
    dmv = pointsVector[pos];
    //std::cout<<"\n\nDMV "<<dmv<<"\n\n Volume medio calculado: "<<dmvPre<<"\n\n";

The code reads a series of contours, calculates and orders their areas, and then uses these areas to calculate metrics such as total volume and a central metric (dmv). The logic behind this appears to be to analyze the distribution of contour areas and find a central point of balance based on volume.

rainyl commented 2 months ago

@gustavovisentini please open new issues for new questions.