【问题标题】:Is it safe to use the same variable as input and output in C++ OpenCV?在 C++ OpenCV 中使用与输入和输出相同的变量是否安全?
【发布时间】:2016-01-03 16:05:27
【问题描述】:

很多OpenCV函数被定义为

function(InputArray src, OutputArray dst, otherargs..)

所以如果我想处理和覆盖同一张图片,我可以这样做吗:

function(myImg, myImg);

这样做安全吗?

谢谢

编辑:

我要求的是 OpenCV 中的标准函数,例如 thresholdblur 等。所以我认为它们应该已经相应地实现了,对吧?

【问题讨论】:

  • 是/否 如果没有记录,则否。
  • 在opencv中它是安全的,但通常会分配新的内存,因此使用不同的输入和输出矩阵头通常更快(如果输出矩阵的类型和大小已经确定,没有新的内存将被分配)。因此,在捕获相机图像并将输入转换为某个输出的典型循环中,transform(input, input) 通常会在每次迭代中分配(并释放)新内存,而 transform(input, output) 只会分配一次内存(在这两种情况下,变量都是在循环之外声明的)。

标签: c++ opencv arguments


【解决方案1】:

是的,在 OpenCV 中它是安全的。


在内部,类似这样的函数:

void somefunction(InputArray _src, OutputArray _dst);

会做类似的事情:

Mat src = _src.getMat();
_dst.create( src.size(), src.type() );
Mat dst = _dst.getMat();

// dst filled with values

所以,如果 srcdst 是:

  • 相同图像,create 实际上不会做任何事情,并且修改实际上是就地。如果操作无法就地进行(例如 OpenCV > 3.2 中的 findConturs),则某些函数可能会在内部 clone src 图像以保证正确的行为。
  • 不同图像,create 将创建一个新矩阵 dst 而不修改 src

文档说明此默认行为不适用。

一个值得注意的例子是findContours,它修改了src 矩阵。您通常会在输入中传递 src.clone() 来应对这种情况,这样只会修改克隆的矩阵,而不会修改您从中克隆的矩阵。

从 OpenCV 3.2 开始,findContours 不会修改输入图像。


感谢Fernando Bertoldi查看答案

【讨论】:

  • 谢谢,我会尽快接受。但是,现在我收到类似于此的错误:stackoverflow.com/questions/17785028/…。你认为这安全有例外吗?
  • @halilpazarlama,是的。有例外,但它们已记录在案(请参阅更新的答案)。您遇到的这个新错误可能是由于缺少标头或库引起的(请参阅该问题中的答案)。
  • @Miki 实际上 srcdst 最终指向同一个内存块,所以你的答案是错误的。由于形状和类型相同,因此不会分配新的内存。对于create,请参阅documentation
  • @FernandoBertoldi 我不知道我为什么写那个废话:)。你显然是对的。不过,在 OpenCV 中这样做是安全。感谢您指出这一点。
  • @Miki 不客气 :) Wrt 是否安全,这取决于操作,问题是文档并不总是清楚它是否安全。例如,显然使用cv::threshold 是安全的,因为OpenCV 的源代码中有一些示例对srcdst 使用相同的参数。
【解决方案2】:

编辑:现在问题已更新,我意识到这无关紧要。不过,我会把它留在这里,以防有人搜索相关问题。


一般来说,对于 C++,这种情况是否安全取决于所讨论的函数体。如果您直接读取和写入同一个变量,您可能会遇到一些严重的逻辑问题。

但是,如果您在覆盖之前使用临时变量来保存原始值,那应该没问题。

但是,如果您正在使用数组,请务必注意。如果您尝试将数组的全部内容存储在临时变量中,则必须小心存储实际数组,而不仅仅是指向它的指针。在许多情况下,通常建议将单个 临时存储在数组中(例如在交换函数中)。但是,在这方面我无法提供更多建议,因为这完全取决于您要做什么。

简而言之,这完全取决于您的函数的实现。

【讨论】:

  • 你是对的,是的,我只是要求 OpenCV 功能。所以我想我是安全的? :)
  • 我猜是这样。根据 Miki 的回答,OpenCV 开发人员在编写代码时考虑了这个逻辑,所以你很好。
猜你喜欢
  • 2015-09-27
  • 1970-01-01
  • 2018-10-09
  • 1970-01-01
  • 2021-12-19
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多