Skip to content
Commit f0d89e98 authored by Maël Valais's avatar Maël Valais
Browse files

AMC-detect: fix errors with OpenCV 3.4.1 by switching from C to C++ API

Starting from OpenCV 3.4.1, the cvSaveImage() function fails with
an exception:

    OpenCV(3.4.1) Error: Assertion failed ((flags & FIXED_TYPE) != 0) in type, file matrix_wrap.cpp, line 807
    libc++abi.dylib: libc++abi.dylib: terminating with uncaught exception of type cv::Exception: OpenCV(3.4.1) matrix_wrap.cpp:807: error: (-215) (flags & FIXED_TYPE) != 0 in function type
    terminating with uncaught exception of type cv::Exception: OpenCV(3.4.1) matrix_wrap.cpp:807: error: (-215) (flags & FIXED_TYPE) != 0 in function type

I could reproduce this bug on Arch, macOS and Ubuntu with OpenCV 3.4.1.
This was working properly until 3.4.0. I opened an issue on the OpenCV
Github repo:

    https://github.com/opencv/opencv/issues/11076

In short: the C API has been deprecated for a long time now, and things
breaks unexcpetedly between versions because it is not maintained.
From https://github.com/opencv/opencv/issues/10246:

> C API support is dropped somewhere before OpenCV 2.x. Again, there
> are no new algorithms developed with C API in OpenCV for the last ~5
> years.

Other links:

    https://github.com/opencv/opencv/pull/10941
    https://github.com/opencv/opencv/issues/10405

Notes when I translated from the C to C++ API:

- cvClearMemStorage is not needed anymore (one of the good thing when using
  the C++ API, storages are handled automatically). Actually, the
  release() was not necessary either but I kept them...
- image->widthStep has been replaced by image.step but in the end it equals
  to image.width * image.channels when using cv::Mat. See:
  http://answers.opencv.org/question/20407/matstep-iplimagewidthstep/
- CV_IMAGE_ELEM was removed. I used the C++ way of accessing the pixels:
  http://answers.opencv.org/question/62848/how-to-convert-cv_image_elem-from-iplimage-to-mat/
- instead of using cvSetImageROI(img), we use a selected part of 'img':
  Mat roi = img(cv::Rect(...))
  See https://funvision.blogspot.fr/2015/12/basic-opencv-3-mat-tutorial-part-2-roi.html
- IplImage had a field 'origin' that would let you know that, if equals to
  1, the image origin is bottom-left, and 0 would be top-left. But when
  translating IplImage to cv::Mat, there does not seem to be an 'origin'
  for cv::Mat (the origin is top-left). This is why the following is
  commented:

      if(src->origin == 1) {
          printf(": Image flip\n");
          cvFlip(*src, NULL, 0);
      }
parent cf9d9f1d
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment