当我们混合 opencv 和 dlib 时,cv::imread() 在 c++ 项目中失败

Posted

技术标签:

【中文标题】当我们混合 opencv 和 dlib 时,cv::imread() 在 c++ 项目中失败【英文标题】:cv::imread() fails in c++ project when we mix opencv and dlib 【发布时间】:2020-05-13 15:57:54 【问题描述】:

我在 Visual Studio 2019 中创建了一个 c++ 项目。我编译并构建了 openCV 4.2.0 版和 dlib 19.19.0 版,并在我的 c++ 项目中使用。我在单个项目中使用 opencv 和 dlib 的座右铭是我想使用 opencv 的 DNN (caffe) 和 dlib 的基于 hog + svm 的人脸检测器 (get_frontal_face_detector()) 进行人脸检测。

我的两个函数是分开的,即detectFaceByOpenCVDNN() 用于基于 opencv 的人脸检测,detectFaceBydlibHOG() 用于基于 dlib 的 HOG + SVM 检测器。

我添加了两个项目的包含目录、lib 目录(附加库目录),并提到了 .lib 文件的附加依赖项。

此项目的构建成功并生成 .lib 文件。通过使用此文件,另一个 c++ 控制台应用程序调用 detectFaceByOpenCVDNN()(opencv 人脸检测器)。

detectFaceByOpenCVDNN()的代码:

#include <opencv2/imgcodecs.hpp>
#include <opencv2/dnn/dnn.hpp>

#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/gui_widgets.h>
#include <dlib/image_io.h>

using namespace dlib;
using namespace std;
using namespace cv::dnn;

void namespace_name::FaceDetection::detectFaceByOpenCVDNN(std::string filename)
    

Net net;        
cv::Mat frame = cv::imread(filename);

if (frame.empty())
    throw std::exception("provided image file is not found or unable to open.");

int frameHeight = frame.rows;
int frameWidth = frame.cols;
    .... // code continues

当我使用此功能时,我收到异常“未找到或无法打开提供的图像文件”。如果frame.empty() 返回true,则抛出。控制台上没有显示其他异常。

虽然只是在挖掘导致此失败的原因,但我知道,如果我从 Properties->Linker->Input->Additional Dependencies 中删除 dlib19.19.0_debug_32bit_msvc1924.lib 条目,则 frame.empty() 返回 false 并且程序继续。

但我还是不明白,为什么我在单个 c++ 项目中使用 opencv 和 dlib 时 cv::imread() 会失败?

【问题讨论】:

您是否使用 libjpeg 和 libpng 静态构建了 dlib?它可能与静态构建到您的 opencv .lib 文件中的那些库的类似副本冲突。如果您不使用这些库,只需重建 dlib 即可。 或者将 opencv 和 dlib 链接到相同的 libjpeg 和 libpng 库。 @DavisKing 您是否使用 libjpeg 和 libpng 静态构建了 dlib? 在 openCV 的 lib 文件夹中我可以看到 libjpeg-turbod.lib 文件,但在 Dlib 的 lib 文件夹中我只能看到dlib19.19.0_debug_32bit_msvc1924.lib 文件。这是否意味着没有 libjpeg 的 Dlib 构建? @DavisKing 在 Cmake 中 DLIB_JPEG_SUPPORT 已开启。成功后我正在重新构建 Dlib。 @DavisKing,宾果游戏!!! :) 伙计,你真是太棒了。正如你所说,这是由于 libjpeg 之间的冲突。 OpenCV 已经使用 libjpeg 构建,并且它的 lib 已经添加到 Additional Dependencies 中,然后,当我构建 dlib 时,我保留了 DLIB_JPEG_SUPPORT 默认值,因此 dlib 也使用 libjpeg 静态构建,因此会发生冲突。谢啦!!我不认为没有这个帮助,我一个人,我可以找到它。 【参考方案1】:

您是否使用 libjpeg 和 libpng 静态构建了 dlib?它可能与静态构建到您的 opencv .lib 文件中的那些库的类似副本冲突。如果您不使用这些库,只需重建 dlib 即可。

或者将 opencv 和 dlib 链接到相同的 libjpeg 和 libpng 库。

Dlib 的 cmake 文件将尝试与 libjpeg 和 libpng 链接,如果找不到系统副本,则会在 dlib/external 中构建并静态链接副本。您可以通过设置DLIB_JPEG_SUPPORTDLIB_PNG_SUPPORT 来控制cmake 是否会尝试链接到这些东西

【讨论】:

我们可以将 DLib 与 OpenCV 的 LIBJPEG 静态库链接起来吗?我们是否应该只构建没有 DLIB_JPEG_SUPPORT 的 DLib 并期望它与 OpenCV 的 LIBJPEG 链接?谢谢。

以上是关于当我们混合 opencv 和 dlib 时,cv::imread() 在 c++ 项目中失败的主要内容,如果未能解决你的问题,请参考以下文章

opencv Mat和Dlib变量类型转换

OpenCV,dlib 地标旋转

opencv基础opencv和dlib库中rectangle类型之间的转换

OpenCV cv::Mat , imshow() , cv::VideoCapture 在运行时不工作

矩形感兴趣区域超出范围时出错 - opencv

尝试将图像与 openCV 混合