13

A lot of OpenCV functions are defined as

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

So if I want to process and overwrite the same image, can I do this:

function(myImg, myImg);

is it safe to do this way?

Thanks

Edit:

I'm asking for the standard functions in OpenCV like threshold, blur etc. So I think they should have been implemented accordingly, right?

jeff
  • 13,055
  • 29
  • 78
  • 136
  • 2
    Yes/No If not documented no. –  Oct 06 '15 at 16:34
  • 1
    in opencv it is safe, but typically new memory will be allocated, so it is often faster to use different input and output matrix header (if type and size of the output matrix is already ok, no new memory will be allocated). So in a typical loop where camera image is captured and input is transformed to some output, transform(input, input) will typically allocate (and free) new memory in each iteration, while transform(input, output) will allocate memory only once (in both cases the variable(s) is/are declared outside of the loop). – Micka Oct 06 '15 at 16:47

2 Answers2

12

Yes, in OpenCV it is safe.


Internally, a function like:

void somefunction(InputArray _src, OutputArray _dst);

will do something like:

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

// dst filled with values

So, if src and dst are:

  • the same image, create won't actually do anything, and the modifications are effectively in-place. Some functions may clone the src image internally if the operation cannot be in-place (e.g. findConturs in OpenCV > 3.2) to guarantee the correct behavior.
  • different images, create will create a new matrix dst without modifying src.

Documentation states where this default behavior doesn't hold.

A notable example is findContours, that modify the src matrix. You cope with this usually passing src.clone() in input, so that only the cloned matrix is modified, but not the one you cloned from.

From OpenCV 3.2, findContours doesn't modify the input image.


Thanks to Fernando Bertoldi for reviewing the answer

Community
  • 1
  • 1
Miki
  • 40,887
  • 13
  • 123
  • 202
  • Thanks I I will accept this ASAP. However, now I get an error similar to this: http://stackoverflow.com/questions/17785028/using-featuredetector-in-opencv-gives-access-violation . Do you think there are exceptions to this being safe? – jeff Oct 06 '15 at 16:42
  • @halilpazarlama, yes. there are exception but they are documented (see updated answer). This new error you have is caused probably from missing headers or libs (see the answer in that question). – Miki Oct 06 '15 at 16:46
  • @Miki actually `src` and `dst` end up pointing to the same memory block, so your answer is wrong. Since the shape and type are the same, new memory is not allocated. See the [documentation](http://docs.opencv.org/3.2.0/d3/d63/classcv_1_1Mat.html#a55ced2c8d844d683ea9a725c60037ad0) for `create`. – Fernando Costa Bertoldi Jan 19 '17 at 17:07
  • @FernandoBertoldi I don't know why I wrote that crap :) . You're obviously right. Still, in OpenCV it's **safe** to do that. Thanks for pointing this out. – Miki Jan 19 '17 at 17:23
  • @Miki you're welcome :) Wrt to it being safe, it depends on the operation, and the problem is that the documentation is not always clear whether it is safe or not. For example, apparently it is safe with `cv::threshold`, since there are examples in OpenCV's source that use the same argument for `src` and `dst`. – Fernando Costa Bertoldi Jan 19 '17 at 17:49
2

EDIT: Now that the question was updated, I realize this is rather irrelevant. I'll leave it here, however, in case someone searching for a related issue comes along.


In general with C++, whether that situation is safe really depends on the body of the function in question. If you are reading from and writing to the same variable directly, you could wind up with some serious logic issues.

However, if you are using a temporary variable to hold the original value before overwriting it, it should be fine.

A MASSIVE word of warning if you're working with arrays, however. If you are trying to store the entire contents of the array in a temporary variable, you have to be careful you're storing the actual array, and not just the pointer to it. In many situations, it would generally be advisable to store individual values in the array temporarily (such as in a swap function). I can't give much further advice in this regard, however, as it all depends on what you're trying to do.

In short, it all depends on your function's implementation.

CodeMouse92
  • 6,840
  • 14
  • 73
  • 130
  • You are right, and yes, I was only asking for OpenCV functions. So I guess I'm safe? :) – jeff Oct 06 '15 at 16:41
  • I would guess so. Based on Miki's answer, the OpenCV developers took this logic into consideration when they wrote their code, so you're good. – CodeMouse92 Oct 06 '15 at 16:42