0

I am trying to make a dip::EuclideanSkeleton. However, when executed, it throws me an Unhandled exception. Is it a mismatch between the return type and the type passed to the function? If so, how can I fix this? I have no more guesses. Without dip::EuclideanSkeleton the program works.


#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <string>
#include "diplib.h"
#include "diplib/file_io.h"
#include "diplib/regions.h"
#include "diplib/display.h"
#include <dip_opencv_interface.h>
#include "diplib/binary.h"
 

int main() {
    cv::Mat img = cv::imread("Cables.jpg", cv::IMREAD_GRAYSCALE);
    if (img.empty()) {
        return -1;
    }
    cv::Mat thresh = img.clone();
    medianBlur(thresh, thresh, 7);
    threshold(thresh, thresh, 127, 255, cv::THRESH_BINARY);
    dip::Image image = dip_opencv::MatToDip(thresh);
    dip::Image conv = dip::EuclideanSkeleton(image);
    cv::Mat final = dip_opencv::DipToMat(conv);

    cv::imshow("", final);
    cv::waitKey(0);
}

in:

  •   dataType_   {dt=UINT8 (1) } dip::DataType
    

out:

  •   dataType_   {dt=SFLOAT (9) } dip::DataType
    

Unhandled exception at 0x00007FF85A0F3B29 in Skel_endpoints.exe: Microsoft C++ exception: dip::ParameterError at memory location 0x000000BAF730EDD8.

1 Answers1

0

The problem is that dip::EuclideanSkeleton expects a binary image, but OpenCV knows no binary type. thresh is of type 8-bit unsigned integer, and when converting to a DIPlib object, the conversion cannot know whether this is meant to be an 8-bit uint image or a binary image. Furthermore, OpenCV uses values of 0 and 255 to represent binary images, whereas DIPlib uses values of 0 and 1. This is described in the documentation.

The solution is to force the 8-bit uint image to binary. The simplest approach is simply comparing to zero: dip_opencv::MatToDip(thresh) > 0. If you do this, you can skip the call to cv::threshold.

Next, the conversion dip_opencv::DipToMat(conv) will produce a CV_8U image, but containing values 0 and 1, not 0 and 255 as expected by other OpenCV functions. Again, one simple approach is to just multiply the result by 255: dip_opencv::DipToMat(conv) * 255.

The program would look like this:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "diplib.h"
#include <dip_opencv_interface.h>
#include "diplib/binary.h"


int main() {
   cv::Mat img = cv::imread("erika.tif", cv::IMREAD_GRAYSCALE);
   if (img.empty()) {
      return -1;
   }
   cv::Mat thresh = img.clone();
   medianBlur(thresh, thresh, 7);
   dip::Image image = dip_opencv::MatToDip(thresh) > 127;
   dip::Image conv = dip::EuclideanSkeleton(image);
   cv::Mat final = dip_opencv::DipToMat(conv) * 255;
   cv::imwrite("foo.png", final);
}

It is unfortunate that MSVC doesn't automatically show the what() string for the uncaught exceptions. I recommend that you put a try/catch block around all your code so that you can display this string. DIPlib gives useful information in exceptions thrown:

int main() {
   try {
      // your code here
   } catch (std::exception const& stde) {
      std::cout << "Caught exception:\n" << stde.what() << '\n';
   }
}
Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • Unfortunately, the modified code throws an exception _Access violation reading location_ in line `dip::Image image = dip_opencv::MatToDip(thresh) > 127;` // I tried to put the code inside _try-catch_ statements, but it didn't help me catch this error. @CrisLuengo –  Sep 24 '20 at 06:17
  • @avenueroan: This code works correctly for me. I don't know how you could get such an access violation error. But then again I don't have a Windows machine to try and figure that out. Did you use the same compiler to build your program as you used for DIPlib and OpenCV? – Cris Luengo Sep 24 '20 at 07:13
  • I built the library using CMake and then connected it to the project. It compiles in Visual Studio 2019. When installing OpenCV, I used a ready-made `.exe` installer with the subsequent installation of dependencies, it definitely works correctly. Perhaps I connected the dependencies of DIPlib incorrectly, but without the `dip::EuclideanSkeleton` everything looks correct. @CrisLuengo –  Sep 24 '20 at 07:33
  • Here is an [error](https://sun7-7.userapi.com/E-2pDsplLf0uLpe18nWBscu7RnyJBJkmi0OPKg/6ZmCsSUHzmc.jpg) that I accidentally found during debugging, although not related to the process of compiling the code. @CrisLuengo –  Sep 24 '20 at 07:45
  • Similarly, if I replace `dip_opencv::MatToDip(thresh) > 127;` to `dip_opencv::MatToDip(thresh)`, then there will be an exception _"Image is not binary"_. // Can you link your source code please? Or it's all the same? –  Sep 24 '20 at 10:59
  • @avenueroan: I've pasted the full program I compiled and ran into the answer. I changed the input file name, and I wrote the output to file instead of `imshow` because I compiled OpenCV without display support. – Cris Luengo Sep 24 '20 at 14:15
  • Regarding the error message: this is likely an error of the static code analyzer. If you don't see any warnings or errors when compiling, then the code is OK. I compile with all possible warnings turned on, and see 0 warnings. I also don't understand how the analyzer doesn't see `Shape` and `dip::Tensor::Shape` being the same type in that context, the code is inside the `dip::Tensor` class. – Cris Luengo Sep 24 '20 at 14:24
  • @avenueroan: if you don’t get any compile-time errors, then include files and linking are correct. The only problem related to linking that I can imagine happening is if you have multiple versions of OpenCV installed, and you’re using the headers of one and the DLL of the other. The other problem could be that the OpenCV DLL you have was compiled in a non-compatible way, maybe using the MinGW compiler of something like that. I would be surprised if this were the issue though. Sorry I can’t debug this problem remotely, I’d need to sit behind your computer... – Cris Luengo Sep 25 '20 at 13:49
  • If you open an issue [here](https://github.com/DIPlib/diplib/issues) maybe someone with access to Windows can try to replicate your problem. – Cris Luengo Sep 25 '20 at 13:50