【问题标题】:How to cast OpenCV cv::Mat as Void pointer?如何将 OpenCV cv::Mat 转换为 Void 指针?
【发布时间】:2021-11-24 06:38:31
【问题描述】:

我在我的项目中使用 3rd 方 SDK,它接受 void * 指针来设置用户特定的元数据。但我的元数据是cv::Mat 格式,因此我需要将cv::Mat 转换为void * 指针,如下所示:

void *set_metadata_ptr(cv::Mat frame)
{

  cv::Mat *user_metadata = new cv::Mat();

  frame.copyTo(*user_metadata);

  return (void *)user_metadata;
}

void foo() 
{
  UserMeta *user_meta = /* ... */;
  user_meta->user_meta_data = (void *)set_metadata_ptr(frame);
}

这很好用,但许多 OpenCV 高级用户不鼓励将指针与 cv::Mat 一起使用,因为 cv::Mat 本身具有 智能指针。我想知道在我的情况下有没有更好的方法将 cv::Mat 转换为 void-pointer?

【问题讨论】:

  • 我认为你的意思是空指针。
  • 你所做的很糟糕,但如果你确保最终删除新对象,这是可以容忍的。 -- 我建议创建没有new(你知道RAII)的Mat,并传递它的地址。 但是确保它的生命周期涵盖了指针的使用! -- 你想要解决的真正的问题是什么?给出上下文。 en.wikipedia.org/wiki/XY_problem
  • 这是一个问得很糟糕的问题。从开始你为什么需要做那个铸造(你写了一些关于第三方库的东西)开始。那么,您正在使用哪个 API 的库是什么,它的功能以及参数必须满足哪些要求。可能需要 void* 的原因有很多,从一些 C 之类的回调到自定义版本的矩阵,再到一些图像表示。
  • 我的超能力说这可能与此有关:stackoverflow.com/a/17137998/1387438

标签: c++ opencv pointers opencv-mat


【解决方案1】:

只需创建自己的包装器:

class MyWrapper {
public:
    cv::Mat frame;
};

像往常一样分配:

MyWrapper *ptr = new MyWrapper();
ptr->frame = myOtherFrame;

然后通过你需要的地方,比如:

user_meta->user_meta_data = (void *) ptr;

请注意,您的方法(在问题中提到)正在执行完整复制,但上面仅保留对现有智能指针的引用。

一个班轮版本:

我们可以将用法缩短为:

user_meta->user_meta_data = (void *) new MyWrapper( frame );

如果我们有一个构造函数,比如:

class MyWrapper {
public:
    explicit MyWrapper(cv::Mat &frame)
        : frame(frame)
    {}

public:
    cv::Mat frame;
};

【讨论】:

  • 这并不能解决问题(调用new,...避免 void 强制转换可能是不可能的)。这是不必要的仪式。而不是这样做,OP可以做他们已经做的事情。它(大部分)是等效的,但不需要额外的类和对象。
  • 记住cv::Mat是一个智能指针,我们只想要一个void *版本;知道进行完整副本(使用frame.copyTo(...))是一种矫枉过正。 OP 建议的是复制和硬编码。但是包装器适用于任何智能指针类型(copyTo 甚至不存在)。
  • 这只是乞求泄漏。谁是主人?所有权是否正在转让?如果是这样,如果回调没有被调用怎么办?为什么需要动态分配?恕我直言,OP 患有隧道视力,而您也加入了他们的行列。这需要后退一步,架构更改为更明智的东西。
  • 我没关系 OP 糟糕地描述了他的问题。很明显,无论如何这是一个糟糕的解决方案。很可能需要指向应计数据的指针,而不是简单的包装器。
  • @DanMašek OP 正在寻求更好的解决方案;他没有抄袭我的;顺便说一句,我们希望任何使用new 的人都知道他们应该在某个时候调用delete,或者你建议我们告诉OP 去重写第三方库吗? (你可以评论他这样的事情,但这是一个答案)
猜你喜欢
  • 2018-04-16
  • 2011-06-28
  • 2016-08-16
  • 2022-06-25
  • 2017-06-03
  • 2013-10-21
  • 1970-01-01
  • 2012-05-07
  • 2022-06-13
相关资源
最近更新 更多