1

I want to implement a function that takes an image as optional parameter. In case an image is passed, I want to use it - otherwise I want to calculate a default value. In the OpenCV library cv::noArray() is used for this purpose. Something like this:

void doStuff(cv::InputArray candidatesMap = cv::noArray())
{
    // initialize candidatesMap if not given
    if(candidatesMap is cv::noArray())  // <-- Need help here
    {
        candidatesMap = createCandidatesMap();
    }

    // ... more code using candidatesMap
}

How can I programmatically check if the optional parameter is given or defaults to cv::noArray().

Since I didn't find any documentation, it might be helpful for others as well.

Sparkofska
  • 1,280
  • 2
  • 11
  • 34

3 Answers3

1

You can do the following to check if an cv::InputArray was assigned to cv::noArray():

void doStuff(cv::InputOutputArray candidatesMap = cv::noArray())
{
    // initialize candidatesMap if not given
    if(candidatesMap.empty())
    {
        candidatesMap = createCandidatesMap();
    }

    // ... more code using candidatesMap
}
Catree
  • 2,477
  • 1
  • 17
  • 24
0

I've checked the usage of the cv::noArray() in the OpenCV code and there is something like this:

if (&argument == &noArray())
    return "InputArrayOfArrays: noArray()";

in your case it would be probably:

void doStuff(cv::InputArray candidatesMap = cv::noArray())
{
    // initialize candidatesMap if not given
    if(&candidatesMap == &cv::noArray())
    {
        candidatesMap = createCandidatesMap();
    }
    // ... more code using candidatesMap
}

But even if candidatesMap is not equal to noArray it doesn't mean that this input is not empty. So it's also worth checking its size.

@MichałWalenciak Said that this comparison wouldn't work. So you can check it in other ways. To check if candidatesMap is valid, you can call candidatesMap.getObj() and check if this pointer is valid or not.

Raffallo
  • 651
  • 8
  • 19
  • @MichałWalenciak These comparations are used in the OpenCV code, so I think that should works. And the `cv::noArray()` is a just global object of an empty `_InputOutputArray` – Raffallo Feb 13 '20 at 11:56
  • Address of function's argument will never be equal to any other variable address in valid c/c++ code. – Michał Walenciak Feb 13 '20 at 12:00
  • @Raffallo Can you point to the corresponding lines in the source code from Github? This would help to understand what is done. – Catree Feb 14 '20 at 10:39
  • @Catree `bindings_utils.cpp` line 13, 43, 80 and 110 in the OpenCV 3 – Raffallo Feb 14 '20 at 10:43
-2

I know it doesn't answer your question, but you can solve your problem by writting cleaner code. Just write two functions. One with parameter and one without.

Michał Walenciak
  • 4,257
  • 4
  • 33
  • 61
  • That might work, but I'm particularly interested in the functionality of `cv::noArray()` – Sparkofska Feb 13 '20 at 11:46
  • Then you cannot. `candidatesMap` is of type `cv::InputArray` and you cannot tell how was it constructed. The only thing you can do is to check `candidatesMap` state. I have never used this type so I cannot tell you for sure, but I'd guess if it was constructed as `noArray` then its size will be 0. Or you can try to compare `candidatesMap` with `cv::InputArray` – Michał Walenciak Feb 13 '20 at 11:50