cv::VideoCapture 在 C# 项目中从 DLL 使用时不会打开文件或流
Posted
技术标签:
【中文标题】cv::VideoCapture 在 C# 项目中从 DLL 使用时不会打开文件或流【英文标题】:cv::VideoCapture doesn't open a file or stream when using it from DLL in C# project 【发布时间】:2019-01-24 02:09:30 【问题描述】:我通过 DllImports 在 C++ 中使用 Unity 的 C# 脚本和 OpenCV。我的目标是在 Unity 场景中创建来自 OpenCV 的视频流。
Unity 加载包含 OpenCV 函数的库。
问题是cv::VideoCapture().open("path_to_file_or_stream")
在从 dll(来自 Unity)调用时总是返回 false。
当我将我的 C++ 代码构建为可执行文件时,一切都很完美。我正在使用 CMAKE 构建我的项目。
# Build exe
ADD_EXECUTABLE($PROJECT_NAME $SRCS_DIR $INCL_DIR)
# Build lib
ADD_LIBRARY($PROJECT_NAME SHARED $SRCS_DIR $INCL_DIR)
# OpenCV
FIND_PACKAGE(OpenCV)
IF(OpenCV_FOUND)
TARGET_LINK_LIBRARIES($PROJECT_NAME PUBLIC $OpenCV_LIBS)
MESSAGE(STATUS "[OpenCV_LIBS] " $OpenCV_LIBS)
ENDIF()
但是,当从 dll 运行时,cv::VideoCapture() 没有打开。
这是我目前掌握的一些代码:
C++/ImageProviderAPI.h
#define IMAGE_API __declspec(dllexport)
extern "C"
...
IMAGE_API ImageProviderAPI* InitProvider(const char* url);
IMAGE_API void StartProvider(ImageProviderAPI* api);
...
class ImageProviderAPI
public:
ImageProviderAPI(std::string url);
~ImageProviderAPI();
void start();
private:
std::string m_url;
cv::VideoCapture* p_videoCapture;
;
C++/ImageProviderAPI.h
IMAGE_API ImageProviderAPI* InitProvider(const char* url)
return new ImageProviderAPI(std::string(url));
IMAGE_API void StartProvider(ImageProviderAPI* api)
api->start();
ImageProviderAPI::ImageProviderAPI(std::string url) :
m_url(url), p_videoCapture(nullptr)
void ImageProviderAPI::start()
p_videoCapture = new cv::VideoCapture();
bool res = p_videoCapture->open(m_url); // m_url - path to file or stream url
// Always false if called from dll
// or this way
p_videoCapture = new cv::VideoCapture(m_url);
bool res = p_videoCapture->isOpened(); // Always false if called from dll
C#/MyScript.cs
public class MyScript: MonoBehaviour
...
[DllImport("ImageProviderAPI.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr InitProvider(string url);
[DllImport("ImageProviderAPI.dll", CharSet = CharSet.Unicode)]
private static extern void StartProvider(IntPtr api);
private IntPtr API;
void Start()
API = InitProvider("path_to_file_or_stream_url");
StartProvider(API);
void Update()
// Do stuff
例如,其他一些 OpenCV 函数,如 cv::imread
、cv::resize
、cv::cvtColor
在从 dll 调用时可以工作。我用std::ofstream
记录了VideoCapture打开结果。
我没想到以 exe 或 dll 运行时有任何区别。也许我在 dll 导入/导出过程中遗漏了一些东西。
【问题讨论】:
我的错误是我忘记检查传递给cv::VideoCapture
的文件路径或流url 字符串。删除CharSet = CharSet.Unicode
即可解决问题。
【参考方案1】:
问题是DllImportAttribute
,尤其是CharSet = CharSet.Unicode
。
要解决它,只需删除 CharSet = CharSet.Unicode
[DllImport("ImageProviderAPI.dll")]
【讨论】:
以上是关于cv::VideoCapture 在 C# 项目中从 DLL 使用时不会打开文件或流的主要内容,如果未能解决你的问题,请参考以下文章
cv::VideoCapture 适用于网络摄像头,但不适用于 IP 摄像头?
cv2.videoCapture.release() 是啥意思?