0

我正在尝试制作一个dip::EuclideanSkeleton. 但是,在执行时,它会抛出一个Unhandled exception。返回类型和传递给函数的类型是否不匹配?如果是这样,我该如何解决这个问题?我没有更多的猜测了。没有dip::EuclideanSkeleton程序的工作。


#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);
}

在:

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

出去:

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

Skel_endpoints.exe 中 0x00007FF85A0F3B29 处未处理的异常:Microsoft C++ 异常:内存位置 0x000000BAF730EDD8 处的 dip::ParameterError。

4

1 回答 1

0

问题是它dip::EuclideanSkeleton需要一个二进制图像,但 OpenCV 不知道二进制类型。thresh是 8 位无符号整数类型,当转换为 DIPlib 对象时,转换无法知道这是 8 位 uint 图像还是二进制图像。此外,OpenCV 使用 0 和 255 的值来表示二进制图像,而 DIPlib 使用 0 和 1 的值。这在文档中有描述

解决方案是强制 8 位 uint 图像为二进制。最简单的方法是简单地与零进行比较:dip_opencv::MatToDip(thresh) > 0. 如果这样做,您可以跳过对 的调用cv::threshold

接下来,转换dip_opencv::DipToMat(conv)将生成一个CV_8U图像,但包含值 0 和 1,而不是其他 OpenCV 函数所期望的 0 和 255。同样,一种简单的方法是将结果乘以 255: dip_opencv::DipToMat(conv) * 255

该程序将如下所示:

#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);
}

不幸的是,MSVC 不会自动显示what()未捕获异常的字符串。我建议您在所有代码周围放置一个try/catch块,以便您可以显示此字符串。DIPlib 在抛出的异常中提供有用的信息:

int main() {
   try {
      // your code here
   } catch (std::exception const& stde) {
      std::cout << "Caught exception:\n" << stde.what() << '\n';
   }
}
于 2020-09-23T15:16:14.060 回答