0

In c++ we can take input parameters and simply return the values to the calling function, but opencv functions take output parameters as function arguments. Are there any performance/interoperability reasons for this? If not, then what are the reasons for this decision?

Mat img = cv::resize(someMat, ...);
cv::resize(someMat, img, ...);
M.Yousuf
  • 53
  • 7
  • possible duplicate: https://stackoverflow.com/questions/12056801/efficiency-of-output-parameter-vs-return-value-on-the-stack-for-stl-data-structu (modulo this is no opencv, but only the implementers of opencv can know why they did it) – 463035818_is_not_an_ai Apr 12 '19 at 13:35
  • Possible duplicate of [Efficiency of output parameter vs return value on the stack for stl data structures](https://stackoverflow.com/questions/12056801/efficiency-of-output-parameter-vs-return-value-on-the-stack-for-stl-data-structu) – mustaccio Apr 12 '19 at 13:37
  • 1
    Before move semantics, it was more efficient to pass by reference, not so much now. Also, if they both have C and C++ libraries to keep up to date, it's probably easier for them to pass by argument in both places so the APIs look pretty much the same. – AlexG Apr 12 '19 at 13:49
  • Thanks for providing the reference, but I have already gone through this. It only addresses the problem in terms of efficiency. I am also interested in some design related reasons. I have changed the question slightly to account for that. – M.Yousuf Apr 14 '19 at 05:29

1 Answers1

2

The existing API is better and faster. It allows not to allocate memory every time. In cv::resize for dst Mat will call cv::Mat::create. But if dst already has the same size and type then it will be without new allocation.

For example I can create image 800x600 and for big video file do resizing each frame into this buffer:

cv::Mat img(800, 600,...); // Initialization and memory allocation
...
for (; cap >> someMat;)
{
    cv::resize(someMat, img, ...); // No memory allocation, resizing into img
}

For this case it will be N memory allocations:

cv::Mat img;
for (; cap >> someMat;)
{
    img = cv::resize(someMat, ...); // New allocation inside cv::resize and free previous value
}
Nuzhny
  • 1,869
  • 1
  • 7
  • 13
  • No, correct. I added links to the implementation of cv::resize and cv::Mat::create. The first case allows reuse memory. And the second - no: in cv::resize will create new cv::Mat dst. – Nuzhny Apr 13 '19 at 12:30
  • Thankx for the great answer !! Are there any interoperability reasons for using this convention? I read somewhere that we can pass multiple types of containers in opencv functions like vector or Mat because these functions are just taking interfaces (e.g, InputArray) as input. – M.Yousuf Apr 14 '19 at 05:19
  • For std::vector will be the same behavior: if size() == newSize then vector.resize() will returns without reallocation. – Nuzhny Apr 15 '19 at 03:12