-
-
Notifications
You must be signed in to change notification settings - Fork 55.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extendible parameters in OpenCV functions #17997
Comments
This is a toy example, which was tested on macOS 10.15.6 with Apple's Clang 11 and GCC 9.2.0 from hpc.sourceforge.net. It should compile and run with any C++ 11 compiler; with C++14 or later it uses aggregate initialization feature Update: in Visual Studio "/std:c++latest" option should be set in order to use the proposed method of passing parameters. However, the parameter declaration and the function itself compile fine when older standards are used. Update 2: added 'call chain' method to set properties in the case of older standards. It's less crisp than C++ 20 version, but shorter than the manual parameter initialization one by one. Hopefully, compilers can optimize such a chain of calls and will not copy the structure each time. But in any case it's very little overhead Update 3: added diagnostic messages, which method we use, and also defined a helper macro to illustrate how it could have been used in OpenCV
|
That looks very promising to me. Especcially because it allows C++20 users to have a more compact function calls. What about optional output arrays that have default initializations? Seems like outputarrays will not work for this. However they can simply be added as default parameters to the function arguments as its currently done i guess. I think that this solution will help with reducing the number of different function overloads to some degree, however it is not possible to completely get rid of multiple overloads. For example in findEssentialMat, most of the times it is handled as if it its the essential matrix between two frames of the same camera, but sometimes users want to specify that it is from two different cameras. So adding the intrinsic calibration parameters for two differnt cameras to the struct could be possible, but i feel like it should be only used for a large overlap. So in the future, should these functions be named slightly different or keeping multiple overloads? I guess some guidelines would then be useful for contributors. I personally currently make use of a implementation of a heterogeneous container (to enable creating plugins that have just a single function with single argument), into which i can store any amount of parameters with type information, value and a key at runtime. So you can dynamically pass any combinations of arguments to the function. This can be really handy for creating pipelines but seems not the right choice for opencv. |
@tompollok, thank you! I think, optional OutputArray and such can be specified using this method:
This approach will not completely eliminate the need for overloaded functions, of course, but will greatly reduce it. Most of the time it can be just overloads, in rare cases it may require different function names. Heterogeneous container solution is one of the option, of course, and we tried it (still use for layer parameters in OpenCV DNN), but it's convenient when you have a whole hierarchy of classes with mostly similar parameters. If you have a flat library of different algorithms, such approach may be too heavy. Besides, there is little support from compiler and IDE. Different usage models need different approaches. |
Ok the provided essential mat example looks good to me. I think your proposal looks sound and the way to go. I also like that there is no strict ordering of the parameters anymore. |
unfortunately, C++ 20 standard and the actual implementations require that the declaration order of the 'params' structure fields and their order in the aggregate initialiser do match. One of the solutions, as suggested above, is to require alphabetically sorted order. But it's better than optional parameters, of course, because 1) you see which parameters get which values, i.e. it's self-documenting and 2) you can indeed skip some parameters that you want to keep default. |
No idea what would be the best solution in C++. I am not a C++ expert. From an user point of view, a Python like syntax, way to call the functions, looks like a good improvement. What about bindings with other languages (Python, Java, ...)? Wondering:
Few examples:
Probably some of these "issues" come from the natural life cycle of a library, like introducing new methods. But I think also a better emphasis on the API quality could avoid some of these issues. At least clear rules and guidelines are needed. Because I am sure there are lots of functions that are not really used, and potentially have some bugs. It is worse with OpenCV contrib where I believe a large part of the code are not really used. |
The Named Parameter idiom (NPI) and method chaining is my preferred approach for opencv. ISOCPP discusses this feature as the Named Parameter Idiom https://isocpp.org/wiki/faq/ctors#named-parameter-idiom From OE34, the author writes this as their view of drawbacks
I agree with that author that NPI is the most powerful solution. However, I disagree with the author in their drawback list when compared to the "make a struct for everything" (MASFE) approach.
|
Hi. I have pushed an example of a new ResultGood news. Works today in both C++ and python. No code change needed to OpenCV 4 for the NPI approach. My example is a simple functor wrapping the existing free-function
Comments
|
The discussion thread for https://github.com/opencv/opencv/wiki/OE-34.-Named-Parameters
The text was updated successfully, but these errors were encountered: