c++ - dip::EuclideanSkeleton不起作用(未处理的异常)

标签 c++ opencv image-processing diplib

我正在尝试制作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
    

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

    最佳答案

    问题是dip::EuclideanSkeleton需要二进制图像,但是OpenCV不知道二进制类型。 thresh是8位无符号整数类型,转换为DIPlib对象时,转换无法知道这是8位uint图像还是二进制图像。此外,OpenCV使用0和255的值表示二进制图像,而DIPlib使用0和1的值。这是described in the documentation
    解决方案是将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';
       }
    }
    

    关于c++ - dip::EuclideanSkeleton不起作用(未处理的异常),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64029804/

    相关文章:

    c++ - 如何在 C++ 中集成 Google 稀疏哈希

    c++ - decltype - "the only context in which a variable defined as a reference is not treated as a synonym for the object to which it refers"?

    c++ - 交叉递归规则声明

    opencv - 将 OpenCV 库与 Armadillo 库结合使用的最佳方法是什么?

    python - 使用 pytesseract OCR 识别图像中的文本

    c++ - 十进制奇偶校验

    python - 阴影去除道路图像

    python - 调用 read() 时 OpenCV (Python) 不更新帧

    image-processing - 用于车辆检测和跟踪的训练数据的图像分辨率?

    c++ - OpenCV:相对于引用图像移动/对齐面部图像(图像配准)