如何使用 c++/cli 从 C# 流到 OpenCV Mat?
Posted
技术标签:
【中文标题】如何使用 c++/cli 从 C# 流到 OpenCV Mat?【英文标题】:How to come from C# stream to OpenCV Mat by using c++/cli? 【发布时间】:2014-02-08 17:13:31 【问题描述】:我正在从 Azure Blob 存储读取一些图像。这是 c# 中的流。
在 c++/cli 中我需要这样做:
cv::Mat img_object = imdecode(data, IMREAD_UNCHANGED);
其中数据的类型为 cv::InputArray
所以问题是我如何最好地从 c# 到 cv::mat?
public ref class Client
public:
// TODO: Add your methods for this class here.
void Method(Stream ^ img1, Stream ^ img2);
;
void Client::Method(...)
我只是输入了 Stream ^ img1,Stream ^img2,这不是必需的,只是不确定从 c# 流到 cv::Mat 类的最佳方法是什么。
我知道我可以将流保存在临时文件位置并使用 imread 代替,但最好在内存中执行。
在 csharp 中我只是有这样的东西:(我知道它不是正确的方法,但为了这个例子的目的,它说明了这一点)。
Client client = new Client();
client.Method(blob.GetStream(), blob.GetStream())
更新:先试试
void CVService::Stiching::StichingClient::FindHomography(cli::array<unsigned char>^ pCBuf1, cli::array<unsigned char> ^ pCBuf2)
pin_ptr<unsigned char> data1 = &pCBuf1[0];
pin_ptr<unsigned char> data2 = &pCBuf2[0];
Mat img_object = imdecode(*data1,IMREAD_COLOR);
Mat img_scene = imdecode(*data2, IMREAD_COLOR);
if (!img_object.data || !img_scene.data)
return;
imwrite("c:\\test.jpg", img_object);
和
public class WebRole : RoleEntryPoint
public override bool OnStart()
// For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
StichingClient client = new StichingClient();
client.FindHomography(ReadByteArray(path1).Result
, ReadByteArray(path2).Result);
return base.OnStart();
private async Task<byte[]> ReadByteArray(string p)
using (var fs = File.OpenRead(p))
using (var ms = new MemoryStream())
await fs.CopyToAsync(ms);
return ms.ToArray();
问题是加载的 cv::mat 的 data== 0 并且没有将图像写入磁盘。我已经验证传递的 char 数组包含数据。有什么方法可以找出为什么 imdecode 不解码图像?
更新 2
c++/cli 代码部分的以下测试有效:
Mat test1 = imread("DSC_023.tif");
std::vector<unsigned char> buf;
imencode(".jpg", test1, buf);
Mat test2 = imdecode(buf, IMREAD_COLOR);
上面 4 行 test2 是加载的图像和 imdecode 作品。所以想知道为什么当数据以字节数组形式出现时它不起作用
【问题讨论】:
让我回顾一下:imdecode 问题归结为:如何从 Task所以这是我的解决方案。它可以被清理掉,但它现在可以工作了。
void CVService::Stiching::StichingClient::FindHomography(cli::array<unsigned char>^ pCBuf1, cli::array<unsigned char> ^ pCBuf2)
pin_ptr<unsigned char> data1 = &pCBuf1[0];
pin_ptr<unsigned char> data2 = &pCBuf2[0];
pin_ptr<System::Byte> p1 = &pCBuf1[0];
unsigned char* pby1 = p1;
Mat img_data1(pCBuf1->Length, 1, CV_8U, pby1);
pin_ptr<System::Byte> p2 = &pCBuf2[0];
unsigned char* pby2 = p2;
Mat img_data2(pCBuf2->Length, 1, CV_8U, pby2);
cv::Mat img_object = imdecode(img_data1, IMREAD_UNCHANGED);
cv::Mat img_scene = imdecode(img_data2, IMREAD_UNCHANGED);
if (!img_object.data || !img_scene.data)
return;
imwrite("img_object.jpg", img_object);
imwrite("img_scene.jpg", img_scene);
我通过转换从内存中的 Azure Blob 存储加载的两个图像来完成这项工作,现在可以对图像执行我的 opencv 操作。这里的测试只是将通过的两张图片写入文件系统。
【讨论】:
正是我需要的。一切都按预期工作,但有一个问题。内存泄漏不会有问题,不需要释放缓冲区吗?我只是在学习 c++,只是想知道 ;) @pksorensen 这将与 cli/cpp 一起使用,可从其他 .net 语言(如 c#)调用。 cli::array 是托管数组,.net 将处理内存,因为它们是在托管部分上创建的。以上是关于如何使用 c++/cli 从 C# 流到 OpenCV Mat?的主要内容,如果未能解决你的问题,请参考以下文章