【问题标题】:dip::EuclideanSkeleton doesn't work (Unhandled exception)dip::EuclideanSkeleton 不起作用(未处理的异常)
【发布时间】:2020-09-23 14:07:35
【问题描述】:

我正在尝试创建dip::EuclideanSkeleton。但是,在执行时,它会抛出一个未处理的异常。返回类型和传递给函数的类型是否不匹配?如果是这样,我该如何解决这个问题?我没有更多的猜测了。没有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。

【问题讨论】:

    标签: c++ opencv image-processing diplib


    【解决方案1】:

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

    解决方法是强制 8 位 uint 图像为二进制。最简单的方法是简单地与零进行比较:dip_opencv::MatToDip(thresh) &gt; 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';
       }
    }
    

    【讨论】:

    • 不幸的是,修改后的代码在dip::Image image = dip_opencv::MatToDip(thresh) &gt; 127;行中抛出了异常访问冲突读取位置 //我试图将代码放入try-catch 声明,但它并没有帮助我发现这个错误。 @CrisLuengo
    • @avenueroan:这段代码对我来说是正确的。我不知道你怎么会得到这样的访问冲突错误。但话又说回来,我没有一台 Windows 机器来尝试解决这个问题。您是否使用与 DIPlib 和 OpenCV 相同的编译器来构建程序?
    • 我使用 CMake 构建了库,然后将其连接到项目。它在 Visual Studio 2019 中编译。在安装 OpenCV 时,我使用了现成的 .exe 安装程序,随后安装了依赖项,它肯定可以正常工作。也许我错误地连接了 DIPlib 的依赖项,但是没有 dip::EuclideanSkeleton 一切看起来都是正确的。 @CrisLuengo
    • 这里是一个error,是我在调试的时候偶然发现的,虽然和编译代码的过程没有关系。 @CrisLuengo
    • 同理,如果我把dip_opencv::MatToDip(thresh) &gt; 127;换成dip_opencv::MatToDip(thresh),就会出现异常"Image is not binary"。 // 你能链接你的源代码吗?还是都一样?
    猜你喜欢
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2016-03-18
    • 2017-06-16
    • 1970-01-01
    相关资源
    最近更新 更多