Closed cv3d closed 5 years ago
enum ACCESS_FLAG
Use 'CamelCase' for types / enums. All capitals letters are reserved for macro / constants itself.
BTW, This is not regular (simple) enum. This is "bit-set" enum, for example: ACCESS_READ | ACCESS_FAST
is valid parameter.
Some design work is required to resolve "enum" handling.
I see these classes of enums used in OpenCV:
operator | ()
(Will it work?). But it is C++ only. What is about Python / Java?CAP_PROP_*
enums. There are many enums, but they are passed to single function (.get()
method). No idea about C++, but in Python we can group them into single enum type:
VideoCaptureProperty.CAP_PROP_GSTREAMER_QUEUE_LENGTH
VideoCaptureProperty.CAP_PROP_IMAGES_BASE
DEFAULT_NLEVELS
. No need to name them. Perhaps some of these enums should be replaced to static const int DEFAULT_NLEVELS = 64;
(there are no more issues with modern compilers anymore) and bindings generator should know themCurrently all enums are "int" contants in Python. This approach is not safe and error prone. It would be nice to introduce real enum types in Python.
Unfortunately, only Python 3.6+ have "native" enum types:
from enum import Enum
class AccessFlag(Enum):
ACCESS_READ = 1 << 24
ACCESS_WRITE = 2 << 24
ACCESS_RW = 3 << 24
...
We should emulate this for other Python versions somehow.
In C++ enum type is not used for accessing of enum value (added to namespace/class): cv::ACCESS_READ
In Python it is required to use enum name: cv.AccessFlag.ACCESS_READ
So probably we should duplicate enum values into current module to save compatibility with existed Python code and keep similarity between C++/Python code:
class AccessFlag(Enum):
ACCESS_READ = 1 << 24
...
ACCESS_READ = AccessFlag.ACCESS_READ
ACCESS_WRITE = AccessFlag.ACCESS_WRITE
alternatively we can try to overload
operator | ()
(Will it work?)
operator | ()
will not work, as it causes issues with Eigen library. Can we define it only for cv
namespace by any chance?
As for link you provided, it seems to refer to operator |= ()
, which I already defined.
Thanks for revisiting enums for OpenCV 4 this was bothering me too.
- enums in classes.
some of those enums in classes are there for encapsulation. However they seem to cause problems for Python wrapper (#10681). Could this be supported for wrapping? Should those enums be moved to be consistent with rest of the OpenCV?
Usage compatibility between C++ and Python
Python enums are basically enum class
in C++11. Making all enums enum class
would be, however, a big disaster (without any backward compatibility stuff).
operator | ()
will not work, as it causes issues with Eigen library.
I can't see why that should cause any issues for Eigen. What was the exact error?
If possible, I think introducing this operator for "flags" enums like this would be quite an easy and backward-compatible way. Of cause wrap this in macro, so we can easily add it for enums that need it. Like CV_FLAGS_ENUM(AccessFlag)
.
I can't see why that should cause any issues for Eigen. What was the exact error?
If I define:
template<typename T, typename std::enable_if< std::is_enum<T>::value >::type* = nullptr>
static T operator|(const T& a, const T& b)
{
typedef typename std::underlying_type<T>::type EnumType;
return static_cast<T>(static_cast<EnumType>(a) | static_cast<EnumType>(b));
}
Then the following errors occurs, and while I can manage the first bullet, I do not know how to fix the second:
ACCESS_READ_FAST = ACCESS_READ | ACCESS_FAST
results in error C2057: expected constant expression
UpperBidiagonalization::DiagVectorType
results in error C2975: '_Options' : invalid template argument for 'Eigen::Matrix', expected compile-time constant expression
Just don't use templates. Separate operator definition for each "flags" enum, something like this:
// in namespace cv
static inline AccessFlags operator | (const AccessFlags& a, const AccessFlags& b)
{
return (AccessFlags)((int)a | (int)b);
}
// this should work now: AccessFlags flags = ACCESS_READ | ACCESS_WRITE;
CV_FLAGS_ENUM(AccessFlag)
I like this idea to declare multiple operators.
that seems to be the same issue. constexpr should fix that.
However, I think it is not a good idea to declare templated operator |()
for all enums. Even though the operator is declared in cv namespace it can be ADL-resolved for user code. That is what happened for Eigen.
@alalek exactly!
To resolve ACCESS_READ_FAST = ACCESS_READ | ACCESS_FAST
error I think you need to make the operator constexpr, so it can be used in constant expressions.
To be specific:
#define CV_FLAGS_ENUM(EnumType) \
static constexpr EnumType operator|(const EnumType &a, const EnumType &b) { \
typedef typename std::underlying_type<EnumType>::type u_type; \
return static_cast<EnumType>(static_cast<u_type>(a) | \
static_cast<u_type>(b)); \
}
(you should add more operators for &, |=, &= etc.)
Then declare
enum AccessFlag { ACCESS_READ=1<<24, ACCESS_WRITE=1<<25,
ACCESS_RW=3<<24, ACCESS_MASK=ACCESS_RW, ACCESS_FAST=1<<26,
ACCESS_READ_FAST = ACCESS_READ | ACCESS_FAST };
CV_FLAGS_ENUM(AccessFlag);
constexpr allows to use the operator in constant expressions.
This approach allows us to declare the operator only for enums where it makes sense.
BTW: I'm not sure if we need ACCESS_READ_FAST
really when we have working operator |()
, but it possible to define it in this way with this approach.
Up until now, it seems Java was not really involved, but we have problems with DescriptorMatcher::MatcherType
enum and the overloaded DescriptorMatcher::create()
.
compile:
[mkdir] Created dir: /build/precommit_linux64/build/java_test/build/classes
[javac] Compiling 55 source files to /build/precommit_linux64/build/java_test/build/classes
[javac] /build/precommit_linux64/build/java_test/src/org/opencv/test/features2d/BruteForceDescriptorMatcherTest.java:84: error: incompatible types: int cannot be converted to String
[javac] matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);
[javac] ^
Java assumes the type of DescriptorMatcher.BRUTEFORCE
to be int
(and all constants in general), thus tried the wrong overloaded variant instead of the enum-based one.
@alalek @hrnr It seems there is a need to update the code generator and pass the enum type to the consts before proceeding any further.
@cv3d You can temporary broke Java detection in CMake via separate "! test" commit, to pass compilation and run other C++/Python tests.
@alalek Java issue has been fixed in #12303.
Kindly be reminded to remove the future
label.
BTW: Shall we merge chunks of this PR every now and then, or shall we make it a huge one?
In Python it is required to use enum name:
cv.AccessFlag.ACCESS_READ
The current wrapper generates: cv.ACCESS_READ
for standard enums,
and cv.AccessFlag_ACCESS_READ
(note the underscore) for C++11 enums (enum class/struct).
Do you want me to map to the C++11 enums to cv.AccessFlag.ACCESS_READ
instead?
cv.AccessFlag.ACCESS_READ
This is preferable way.
BTW,
Perhaps in case of using C++11 enums entry names should be reviewed.
There is no reason to duplicate ACCESS_
prefix: cv::AccessFlag::READ
.
So lets leave strict rules for C++11 enums out of scope for now.
Hi, I have just got back from the holiday. Great progress on this. If you want some help with boring parts of this let me know.
Could this be supported for wrapping? Should those enums be moved to be consistent with rest of the OpenCV?
@hrnr This is my main goal, actually. I might consider that soon enough after I get ride of the temporary operators in this PR. BTW: you can check #12269 and #12303 for my other Python-related PRs, in which binding is now much more easier, and it is getting C++11 ready.
@alalek @hrnr I introduced the following:
ElemDepth
type to represents CV_8U
and sistersElemType
type to represents CV_8UC1
and sistersWhich leads to this logical:
CV_8U
and CV_8UC1
are not the same C++ typeMat.create
expects a type, CV_8U
will not work, but CV_8UC1
or CV_MAKETYPE(CV_8U, 1)
willconvertTo
and assignTo
take only ElemDepth
since the channels are kept intact. Thus CV_8UC1
will not work, but CV_MAT_DEPTH(CV_8UC1)
or CV_8U
will.Currently, the implementation is not complete, and perhaps only the core module can compile. Therefore, defining the prerocessor __cv_strict_types
is required to turn this experimental behavior on.
I think there is a need to define some macros to simplify some task, such as comparing depth types to get the bigger one.
BTW: The work load of ElemDepth
and ElemType
enums is more than what I expected. So, how about we merge the current commits and collaborate on the remaining?
You are really brave to touch this, I wouldn't dare. :-) I think the current strict version will literally break all the existing opencv code.
I see three alternatives:
add overload to all relevant functions to accept both types. Later the overloads could be deprecated. (I don't believe this will ever happen.) Those overloads could be also targeted using clang auto-refactoring tools.
Make them both the same type.
Keep all the functions accepting ints.
First two alternatives will probably break some opencv code, but the impact should be pretty minimal. They shouldn't break much of the user code. The last one seems to be a safe bet, although it is not type-safe.
@hrnr I like the idea of overloads with deprecation notice, but I wonder how likely it can be implemented. Actually I am thinking of dropping the depth and type enums and just make the ints for the time being, but before that, I would give it another day or so.
I think it should be pretty straightforward to implement. My comment was just about the deprecation notice, that would introduce a lot of warnings. That is IMHO unrealistic to do without tool support.
If you don't want to touch this after all, I think you can still leave those two enums there. Enums are implicitly convertible to ints, so it shouldn't break much of the code. However, I may be wrong here, as this is also a dark corner for me.
@alalek Are there any files I should not touch? I feel like there are some that are meant to be C-only, and I wonder if it is still the case even in OpenCV v4
@cv3d Ignore legacy C API.
Great work!
But we need to ensure that "switch with deprecation notice" works really, because changes can be really massive in user code.
Notes:
modules/core/include/opencv2/core/hal/interface.h
Lets keep this file C compatible. Please add #ifdef __cplusplus
and restore #define CV_8U 0
defines in "#else" branch.
Please don't force enum types in "hal" includes (keep "int"), like this:
CV_EXPORTS void cvtGraytoBGR(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int depth, int dcn);
Lets update only general public OpenCV C++ API
If there is some issues with InputArray
classes then you may leave them "as is" (they are not designed for using by OpenCV users directly, except may be algorithms developers).
@alalek This build reports an error in test_superres
without an actual error. Can you double check?
This is sporadic failure (not related to your patch).
we need to ensure that "switch with deprecation notice" works really
@alalek How about cross validation? Previously compiled opencv_test_*
and opencv_perf_*
can be utilized to test the new interface, cannot they?
- p = cv::Mat(3, N, CV_64F);
+ p = cv::Mat(3, N, CV_64FC1);
- z = cv::Mat(3, N, CV_64F);
+ z = cv::Mat(3, N, CV_64FC1);
- mn = cv::Mat::zeros(3, 1, CV_64F);
+ mn = cv::Mat::zeros(3, 1, CV_64FC1);
I agree that this proposed interface is stronger.
But there is a lot of user code that already using Depth instead of Type in Mat constructors. We can't fix their code. Also we should not make a lot of pain due OpenCV upgrade.
Lets make old existed code to work too. Don't break it. For example, add overloads for constructors which accepts Depth too (inline overload which just casts depth->type and then calls correct constructor with "type").
Lets make old existed code to work too
This is on my schedule, but now I am still busy extending the new interface to fully cover the functionalities.
@cv3d, first of all, thank you for all the patches that you prepare for the library, it's truly great and useful work! And this patch will certainly makes the API more convenient, less error-prone and also will make debugging more convenient.
I will elaborate at bit what @alalek said - we've discussed your patch today in the office. It seems like a great idea to replace all macros with enumerations, and in most cases it works well. But when we try to do so with CV_8U ... CV_64F
, CV_8UC1 ... CV_64FC4
etc. - we break too much stuff. I think, you've noticed it too when working on the patch. And the main problem is that it's not just OpenCV code itself that needs to be extensively patched. I foresee that with such a change many, many users will have to patch their code as well, since CV_8U
becomes different from CV_8UC1
etc.
So, we need to undo this part of the patch. I don't know what would be the easiest way - either to undo all such changes or close this PR, open fresh one and copy the necessary changes without touching depth and type macros. In any case, I suggest to split this patch into several ones, and also start with the high-level algorithms that have little code dependent on them. E.g. refactoring everything in features2d and related samples - this can be one patch. Refactoring everything in calib3d - the second one etc. When you get to some enumerations that require dozens of files to be changed, probably it may sense to ask yourself and maybe us - whether it's worth to do. May be not. Compatibility is the priority number one, convenience is the priority number 2 - most of the time and especially when we talk about very basic stuff.
We are releasing OpenCV 4.0 beta next week and then OpenCV 4.0 final in about 1-1.5 months from now. Let's target OpenCV 4.0 final (I believe, there will be some 4.0rc or something like that).
What do you think?
@vpisarev I know you are concerned about backwards compatibility, so do I. But I believe I can provide a fully backwards compatible version of this PR in two days, so how about you give it a check by then? Of course I will split the test commits into smaller chunks, and I hope you can accept it into the first beta release. In fact, I am working myself hard to get it merged before first release. So how about you consider that?
If you are concerned about the current strict version I am writing, then have no worries, as I am making it so only to enforce good practices inside the library itself, but once I finish I will relax that, and let it accept the legacy input as well, perhaps with a warning message that appears only once.
@alalek I would really appreciate it if you can help me understanding why this build is getting bad accuracy on test_core
.
If __cv_strict_types
is not set, it just works great, and I beleive all the #if and #else parts around __cv_strict_types
are equivalent.. Any idea?
@alalek Since this PR changes a lot of files, surely you will have frequent conflicts when merging any future PRs from 3.4 branch into master. To reduce such conflicts, how about we first ship these commits to 3.4 branch with typedef int
instead of the newly introduced enums, and then, in master, we utilize the enums..
There is really huge conflict with another huge patch: #11630 I will try to rebase this patch and resolve conflicts myself and provide link on updated commits.
Do you mean typedef int ElemType;
and update all interfaces ?
It makes sense, but need to check/update bindings parser to understand this. But this will not avoid these conflicts.
typedef int ElemType;
Yes. if we can merge a PR that looks like this into 3.4 with typedef int
instead of the enums, then at least we can guarantee no more similar conflicts like the current one happens.
Hi,
I have read though the current patch.
I was just wondering if you think it would make sense to introduce the compatibility overloads first, without touching much of tests and code.
The patch would be much smaller, with less conflicts. We would be also pretty sure that the patch does not break user code if it requires no substantial changes in opencv.
Later, we can fix the usage of the overloads in OpenCV and possibly also disable them for opencv builds.
Cheers, Jiri
@hrnr It makes sense, but the library would remain type-unsafe from inside, and I doubt it would get ride of such weakness for a long time. Instead, the current approach makes OpenCV a type-safe library in no-time, then we can utilize utilize cross validation to make sure it is compatible with its int-based interface. Furthermore, with a small warning message, even users will gradually catch up to the type-safe API.
If OpenCV 4 is released without deprecating the int-based interface, I suspect it would get deprecated ever...
@cv3d Commits are on this branch in my fork: https://github.com/alalek/opencv/tree/pr12288_rebase
@hrnr Right, we can use non-core OpenCV code / tests as "user code", which we should not break.
@cv3d, well, one of the acceptance criteria for me would be - users do not have to change all CV_32F
to CV_32FC1
etc. And in general CV_...
and CV_...C1
should be identical entities, not different. In your patch this is quite big fraction of all changes. Otherwise, ok, I will definitely review the patch as soon as you finish it.
@alalek @vpisarev @hrnr Here is a summary of the changes in the API. I suspect I changed some APIs that you do not want it to be changed, but please be reminded the overloaded interface should compensate for that. However, if you really insist on a change, then please let me know.
BTW: There are array and raw pointer-based APIs, should not that be replaced with vector and smart pointers?
Before | After |
---|---|
void cv::add(Mat src1, Mat src2, Mat &dst, Mat mask = Mat(), int dtype = -1) |
void cv::add(Mat src1, Mat src2, Mat &dst, Mat mask = Mat(), ElemDepth ddepth = CV_DEPTH_UNSPECIFIED) |
void cv::subtract(Mat src1, Mat src2, Mat &dst, Mat mask = Mat(), int dtype = -1) |
void cv::subtract(Mat src1, Mat src2, Mat &dst, Mat mask = Mat(), ElemDepth ddepth = CV_DEPTH_UNSPECIFIED) |
void cv::multiply(Mat src1, Mat src2, Mat &dst, double scale = 1, int dtype = -1) |
void cv::multiply(Mat src1, Mat src2, Mat &dst, double scale = 1, ElemDepth ddepth = CV_DEPTH_UNSPECIFIED) |
void cv::divide(Mat src1, Mat src2, Mat &dst, double scale = 1, int dtype = -1) |
void cv::divide(Mat src1, Mat src2, Mat &dst, double scale = 1, ElemDepth ddepth = CV_DEPTH_UNSPECIFIED) |
void cv::divide(double scale, Mat src2, Mat &dst, int dtype = -1) |
void cv::divide(double scale, Mat src2, Mat &dst, ElemDepth ddepth = CV_DEPTH_UNSPECIFIED) |
void cv::addWeighted(Mat src1, double alpha, Mat src2, double beta, double gamma, Mat &dst, int dtype = -1) |
void cv::addWeighted(Mat src1, double alpha, Mat src2, double beta, double gamma, Mat &dst, ElemDepth ddepth = CV_DEPTH_UNSPECIFIED) |
void cv::batchDistance(Mat src1, Mat src2, Mat &dist, int dtype, Mat &nidx, int normType = NORM_L2, int K = 0, Mat mask = Mat(), int update = 0, bool crosscheck = false) |
void cv::batchDistance(Mat src1, Mat src2, Mat &dist, ElemType dtype, Mat &nidx, int normType = NORM_L2, int K = 0, Mat mask = Mat(), int update = 0, bool crosscheck = false) |
void cv::normalize(Mat src, Mat &dst, double alpha = 1, double beta = 0, int norm_type = NORM_L2, int dtype = -1, Mat mask = Mat()) |
void cv::normalize(Mat src, Mat &dst, double alpha = 1, double beta = 0, int norm_type = NORM_L2, ElemDepth ddepth = CV_DEPTH_UNSPECIFIED, Mat mask = Mat()) |
void cv::reduce(Mat src, Mat &dst, int dim, int rtype, int dtype = -1) |
void cv::reduce(Mat src, Mat &dst, int dim, int rtype, ElemDepth ddepth = CV_DEPTH_UNSPECIFIED) |
void cv::mulTransposed(Mat src, Mat &dst, bool aTa, Mat delta = Mat(), double scale = 1, int dtype = -1) |
void cv::mulTransposed(Mat src, Mat &dst, bool aTa, Mat delta = Mat(), double scale = 1, ElemDepth ddepth = CV_DEPTH_UNSPECIFIED) |
void cv::calcCovarMatrix(const Mat* samples, int nsamples, Mat &covar, Mat &mean, int flags, int ctype = CV_64F) |
void cv::calcCovarMatrix(const Mat* samples, int nsamples, Mat &covar, Mat &mean, int flags, ElemType ctype = CV_64FC1) |
void cv::calcCovarMatrix(Mat samples, Mat &covar, Mat &mean, int flags, int ctype = CV_64F) |
void cv::calcCovarMatrix(Mat samples, Mat &covar, Mat &mean, int flags, ElemType ctype = CV_64FC1) |
char* cv::depthToString(int depth) |
char* cv::depthToString(ElemDepth depth) |
String cv::typeToString(int type) |
String cv::typeToString(ElemType type) |
char* cv::detail::depthToString_(int depth) |
char* cv::detail::depthToString_(ElemDepth depth) |
cv::String cv::detail::typeToString_(int type) |
cv::String cv::detail::typeToString_(ElemType type) |
void cv::detail::check_failed_MatDepth(const int v1, const int v2, const CheckContext &ctx) |
void cv::detail::check_failed_MatDepth(const ElemDepth v1, const ElemDepth v2, const CheckContext &ctx) |
void cv::detail::check_failed_MatType(const int v1, const int v2, const CheckContext &ctx) |
void cv::detail::check_failed_MatType(const ElemType v1, const ElemType v2, const CheckContext &ctx) |
void cv::detail::check_failed_MatDepth(const int v, const CheckContext &ctx) |
void cv::detail::check_failed_MatDepth(const ElemDepth v, const CheckContext &ctx) |
void cv::detail::check_failed_MatType(const int v, const CheckContext &ctx) |
void cv::detail::check_failed_MatType(const ElemType v, const CheckContext &ctx) |
cv::cuda::GpuMat(int rows, int cols, int type, GpuMat_Allocator* allocator = GpuMat::defaultAllocator()) |
cv::cuda::GpuMat(int rows, int cols, ElemType type, GpuMat_Allocator* allocator = GpuMat::defaultAllocator()) |
cv::cuda::GpuMat(Size size, int type, GpuMat_Allocator* allocator = GpuMat::defaultAllocator()) |
cv::cuda::GpuMat(Size size, ElemType type, GpuMat_Allocator* allocator = GpuMat::defaultAllocator()) |
cv::cuda::GpuMat(int rows, int cols, int type, Scalar s, GpuMat_Allocator* allocator = GpuMat::defaultAllocator()) |
cv::cuda::GpuMat(int rows, int cols, ElemType type, Scalar s, GpuMat_Allocator* allocator = GpuMat::defaultAllocator()) |
cv::cuda::GpuMat(Size size, int type, Scalar s, GpuMat_Allocator* allocator = GpuMat::defaultAllocator()) |
cv::cuda::GpuMat(Size size, ElemType type, Scalar s, GpuMat_Allocator* allocator = GpuMat::defaultAllocator()) |
cv::cuda::GpuMat(int rows, int cols, int type, void* data, size_t step = Mat::AUTO_STEP) |
cv::cuda::GpuMat(int rows, int cols, ElemType type, void* data, size_t step = Mat::AUTO_STEP) |
cv::cuda::GpuMat(Size size, int type, void* data, size_t step = Mat::AUTO_STEP) |
cv::cuda::GpuMat(Size size, ElemType type, void* data, size_t step = Mat::AUTO_STEP) |
void cv::cuda::GpuMat::create(int rows, int cols, int type) |
void cv::cuda::GpuMat::create(int rows, int cols, ElemType type) |
void cv::cuda::GpuMat::create(Size size, int type) |
void cv::cuda::GpuMat::create(Size size, ElemType type) |
void cv::cuda::GpuMat::convertTo(Mat &dst, int rtype) |
void cv::cuda::GpuMat::convertTo(Mat &dst, ElemDepth ddepth) |
void cv::cuda::GpuMat::convertTo(Mat &dst, int rtype, Stream &stream) |
void cv::cuda::GpuMat::convertTo(Mat &dst, ElemDepth ddepth, Stream &stream) |
void cv::cuda::GpuMat::convertTo(Mat &dst, int rtype, double alpha, double beta = 0::0) |
void cv::cuda::GpuMat::convertTo(Mat &dst, ElemDepth ddepth, double alpha, double beta = 0::0) |
void cv::cuda::GpuMat::convertTo(Mat &dst, int rtype, double alpha, Stream &stream) |
void cv::cuda::GpuMat::convertTo(Mat &dst, ElemDepth ddepth, double alpha, Stream &stream) |
void cv::cuda::GpuMat::convertTo(Mat &dst, int rtype, double alpha, double beta, Stream &stream) |
void cv::cuda::GpuMat::convertTo(Mat &dst, ElemDepth ddepth, double alpha, double beta, Stream &stream) |
void cv::cuda::GpuMat::assignTo(GpuMat &m, int type = -1) |
void cv::cuda::GpuMat::assignTo(GpuMat &m, ElemDepth depth = CV_DEPTH_UNSPECIFIED) |
int cv::cuda::GpuMat::type() |
ElemType cv::cuda::GpuMat::type() |
int cv::cuda::GpuMat::depth() |
ElemDepth cv::cuda::GpuMat::depth() |
void cv::cuda::createContinuous(int rows, int cols, int type, Mat &arr) |
void cv::cuda::createContinuous(int rows, int cols, ElemType type, Mat &arr) |
void cv::cuda::ensureSizeIsEnough(int rows, int cols, int type, Mat &arr) |
void cv::cuda::ensureSizeIsEnough(int rows, int cols, ElemType type, Mat &arr) |
GpuMat cv::cuda::BufferPool::getBuffer(int rows, int cols, int type) |
GpuMat cv::cuda::BufferPool::getBuffer(int rows, int cols, ElemType type) |
GpuMat cv::cuda::BufferPool::getBuffer(Size size, int type) |
GpuMat cv::cuda::BufferPool::getBuffer(Size size, ElemType type) |
cv::cuda::HostMem(int rows, int cols, int type, HostMem_AllocType alloc_type = HostMem::AllocType::PAGE_LOCKED) |
cv::cuda::HostMem(int rows, int cols, ElemType type, HostMem_AllocType alloc_type = HostMem::AllocType::PAGE_LOCKED) |
cv::cuda::HostMem(Size size, int type, HostMem_AllocType alloc_type = HostMem::AllocType::PAGE_LOCKED) |
cv::cuda::HostMem(Size size, ElemType type, HostMem_AllocType alloc_type = HostMem::AllocType::PAGE_LOCKED) |
void cv::cuda::HostMem::create(int rows, int cols, int type) |
void cv::cuda::HostMem::create(int rows, int cols, ElemType type) |
int cv::cuda::HostMem::type() |
ElemType cv::cuda::HostMem::type() |
int cv::cuda::HostMem::depth() |
ElemDepth cv::cuda::HostMem::depth() |
int cv::directx::getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT) |
ElemType cv::directx::getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT) |
int cv::directx::getTypeFromD3DFORMAT(const int iD3DFORMAT) |
ElemType cv::directx::getTypeFromD3DFORMAT(const int iD3DFORMAT) |
enum cv::<unnamed> { ... } |
enum cv::AccessFlag { ... } |
enum cv::_InputArray::<unnamed> { ... } |
enum cv::_InputArray::KindFlag { ... } |
enum cv::_OutputArray::<unnamed> { ... } |
enum cv::_OutputArray::DepthMask { ... } |
enum cv::UMatData::<unnamed> { ... } |
enum cv::UMatData::MemoryFlag { ... } |
void cv::ocl::convertFromBuffer(void* cl_mem_buffer, size_t step, int rows, int cols, int type, UMat &dst) |
void cv::ocl::convertFromBuffer(void* cl_mem_buffer, size_t step, int rows, int cols, ElemType type, UMat &dst) |
char* cv::ocl::convertTypeStr(int sdepth, int ddepth, int cn, c_string buf) |
char* cv::ocl::convertTypeStr(ElemDepth sdepth, ElemDepth ddepth, int cn, c_string buf) |
String cv::ocl::kernelToStr(Mat _kernel, int ddepth = -1, const c_string name = 0) |
String cv::ocl::kernelToStr(Mat _kernel, ElemDepth ddepth = CV_DEPTH_UNSPECIFIED, const c_string name = 0) |
GpuMat cv::cuda::getOutputMat(Mat &_dst, int rows, int cols, int type, Stream &stream) |
GpuMat cv::cuda::getOutputMat(Mat &_dst, int rows, int cols, ElemType type, Stream &stream) |
cv::UMat(int rows, int cols, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT) |
cv::UMat(int rows, int cols, ElemType type, UMatUsageFlags usageFlags = USAGE_DEFAULT) |
cv::UMat(Size size, int type, UMatUsageFlags usageFlags = USAGE_DEFAULT) |
cv::UMat(Size size, ElemType type, UMatUsageFlags usageFlags = USAGE_DEFAULT) |
cv::UMat(int rows, int cols, int type, const Scalar &s, UMatUsageFlags usageFlags = USAGE_DEFAULT) |
cv::UMat(int rows, int cols, ElemType type, const Scalar &s, UMatUsageFlags usageFlags = USAGE_DEFAULT) |
cv::UMat(Size size, int type, const Scalar &s, UMatUsageFlags usageFlags = USAGE_DEFAULT) |
cv::UMat(Size size, ElemType type, const Scalar &s, UMatUsageFlags usageFlags = USAGE_DEFAULT) |
Mat cv::getGaussianKernel(int ksize, double sigma, int ktype = CV_64F) |
Mat cv::getGaussianKernel(int ksize, double sigma, ElemType ktype = CV_64FC1) |
void cv::getDerivKernels(Mat &kx, Mat &ky, int dx, int dy, int ksize, bool normalize = false, int ktype = CV_32F) |
void cv::getDerivKernels(Mat &kx, Mat &ky, int dx, int dy, int ksize, bool normalize = false, ElemType ktype = CV_32FC1) |
Mat cv::getGaborKernel(Size ksize, double sigma, double theta, double lambd, double gamma, double psi = CV_PI*0::5, int ktype = CV_64F) |
Mat cv::getGaborKernel(Size ksize, double sigma, double theta, double lambd, double gamma, double psi = CV_PI*0::5, ElemType ktype = CV_64FC1) |
void cv::boxFilter(Mat src, Mat &dst, int ddepth, Size ksize, Point anchor = Point(-1,-1), bool normalize = true, int borderType = BORDER_DEFAULT) |
void cv::boxFilter(Mat src, Mat &dst, ElemDepth ddepth, Size ksize, Point anchor = Point(-1,-1), bool normalize = true, int borderType = BORDER_DEFAULT) |
void cv::sqrBoxFilter(Mat _src, Mat &_dst, int ddepth, Size ksize, Point anchor = Point(-1, -1), bool normalize = true, int borderType = BORDER_DEFAULT) |
void cv::sqrBoxFilter(Mat _src, Mat &_dst, ElemDepth ddepth, Size ksize, Point anchor = Point(-1, -1), bool normalize = true, int borderType = BORDER_DEFAULT) |
void cv::filter2D(Mat src, Mat &dst, int ddepth, Mat kernel, Point anchor = Point(-1,-1), double delta = 0, int borderType = BORDER_DEFAULT) |
void cv::filter2D(Mat src, Mat &dst, ElemDepth ddepth, Mat kernel, Point anchor = Point(-1,-1), double delta = 0, int borderType = BORDER_DEFAULT) |
void cv::sepFilter2D(Mat src, Mat &dst, int ddepth, Mat kernelX, Mat kernelY, Point anchor = Point(-1,-1), double delta = 0, int borderType = BORDER_DEFAULT) |
void cv::sepFilter2D(Mat src, Mat &dst, ElemDepth ddepth, Mat kernelX, Mat kernelY, Point anchor = Point(-1,-1), double delta = 0, int borderType = BORDER_DEFAULT) |
void cv::Sobel(Mat src, Mat &dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT) |
void cv::Sobel(Mat src, Mat &dst, ElemDepth ddepth, int dx, int dy, int ksize = 3, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT) |
void cv::Scharr(Mat src, Mat &dst, int ddepth, int dx, int dy, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT) |
void cv::Scharr(Mat src, Mat &dst, ElemDepth ddepth, int dx, int dy, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT) |
void cv::Laplacian(Mat src, Mat &dst, int ddepth, int ksize = 1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT) |
void cv::Laplacian(Mat src, Mat &dst, ElemDepth ddepth, int ksize = 1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT) |
void cv::convertMaps(Mat map1, Mat map2, Mat &dstmap1, Mat &dstmap2, int dstmap1type, bool nninterpolation = false) |
void cv::convertMaps(Mat map1, Mat map2, Mat &dstmap1, Mat &dstmap2, ElemType dstmap1type, bool nninterpolation = false) |
void cv::integral(Mat src, Mat &sum, int sdepth = -1) |
void cv::integral(Mat src, Mat &sum, ElemDepth sdepth = CV_DEPTH_UNSPECIFIED) |
void cv::integral(Mat src, Mat &sum, Mat &sqsum, int sdepth = -1, int sqdepth = -1) |
void cv::integral(Mat src, Mat &sum, Mat &sqsum, ElemDepth sdepth = CV_DEPTH_UNSPECIFIED, ElemDepth sqdepth = CV_DEPTH_UNSPECIFIED) |
void cv::integral(Mat src, Mat &sum, Mat &sqsum, Mat &tilted, int sdepth = -1, int sqdepth = -1) |
void cv::integral(Mat src, Mat &sum, Mat &sqsum, Mat &tilted, ElemDepth sdepth = CV_DEPTH_UNSPECIFIED, ElemDepth sqdepth = CV_DEPTH_UNSPECIFIED) |
void cv::createHanningWindow(Mat &dst, Size winSize, int type) |
void cv::createHanningWindow(Mat &dst, Size winSize, ElemType type) |
void cv::initUndistortRectifyMap(Mat cameraMatrix, Mat distCoeffs, Mat R, Mat newCameraMatrix, Size size, int m1type, Mat &map1, Mat &map2) |
void cv::initUndistortRectifyMap(Mat cameraMatrix, Mat distCoeffs, Mat R, Mat newCameraMatrix, Size size, ElemType m1type, Mat &map1, Mat &map2) |
float cv::initWideAngleProjMap(Mat cameraMatrix, Mat distCoeffs, Size imageSize, int destImageWidth, int m1type, Mat &map1, Mat &map2, int projType = PROJ_SPHERICAL_EQRECT, double alpha = 0) |
float cv::initWideAngleProjMap(Mat cameraMatrix, Mat distCoeffs, Size imageSize, int destImageWidth, ElemType m1type, Mat &map1, Mat &map2, int projType = PROJ_SPHERICAL_EQRECT, double alpha = 0) |
void cv::hal::filter2D(int stype, int dtype, int kernel_type, uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int full_width, int full_height, int offset_x, int offset_y, uchar* kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y, double delta, int borderType, bool isSubmatrix) |
void cv::hal::filter2D(ElemType stype, ElemType dtype, ElemType kernel_type, uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int full_width, int full_height, int offset_x, int offset_y, uchar* kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y, double delta, int borderType, bool isSubmatrix) |
void cv::hal::sepFilter2D(int stype, int dtype, int ktype, uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int full_width, int full_height, int offset_x, int offset_y, uchar* kernelx_data, int kernelx_len, uchar* kernely_data, int kernely_len, int anchor_x, int anchor_y, double delta, int borderType) |
void cv::hal::sepFilter2D(ElemType stype, ElemType dtype, ElemType ktype, uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int full_width, int full_height, int offset_x, int offset_y, uchar* kernelx_data, int kernelx_len, uchar* kernely_data, int kernely_len, int anchor_x, int anchor_y, double delta, int borderType) |
void cv::hal::morph(int op, int src_type, int dst_type, uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int roi_width, int roi_height, int roi_x, int roi_y, int roi_width2, int roi_height2, int roi_x2, int roi_y2, int kernel_type, uchar* kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y, int borderType, const double* borderValue[4], int iterations, bool isSubmatrix) |
void cv::hal::morph(int op, ElemType src_type, ElemType dst_type, uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int roi_width, int roi_height, int roi_x, int roi_y, int roi_width2, int roi_height2, int roi_x2, int roi_y2, int kernel_type, uchar* kernel_data, size_t kernel_step, int kernel_width, int kernel_height, int anchor_x, int anchor_y, int borderType, const double* borderValue[4], int iterations, bool isSubmatrix) |
void cv::hal::resize(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, double inv_scale_x, double inv_scale_y, int interpolation) |
void cv::hal::resize(ElemType src_type, const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, double inv_scale_x, double inv_scale_y, int interpolation) |
void cv::hal::warpAffine(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, const double* M[6], int interpolation, int borderType, const double* borderValue[4]) |
void cv::hal::warpAffine(ElemType src_type, const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, const double* M[6], int interpolation, int borderType, const double* borderValue[4]) |
void cv::hal::warpPerspective(int src_type, const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, const double* M[9], int interpolation, int borderType, const double* borderValue[4]) |
void cv::hal::warpPerspective(ElemType src_type, const uchar* src_data, size_t src_step, int src_width, int src_height, uchar* dst_data, size_t dst_step, int dst_width, int dst_height, const double* M[9], int interpolation, int borderType, const double* borderValue[4]) |
void cv::hal::cvtBGRtoBGR(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int scn, int dcn, bool swapBlue) |
void cv::hal::cvtBGRtoBGR(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, ElemDepth depth, int scn, int dcn, bool swapBlue) |
void cv::hal::cvtBGRtoGray(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int scn, bool swapBlue) |
void cv::hal::cvtBGRtoGray(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, ElemDepth depth, int scn, bool swapBlue) |
void cv::hal::cvtGraytoBGR(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int dcn) |
void cv::hal::cvtGraytoBGR(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, ElemDepth depth, int dcn) |
void cv::hal::cvtBGRtoYUV(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int scn, bool swapBlue, bool isCbCr) |
void cv::hal::cvtBGRtoYUV(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, ElemDepth depth, int scn, bool swapBlue, bool isCbCr) |
void cv::hal::cvtYUVtoBGR(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int dcn, bool swapBlue, bool isCbCr) |
void cv::hal::cvtYUVtoBGR(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, ElemDepth depth, int dcn, bool swapBlue, bool isCbCr) |
void cv::hal::cvtBGRtoXYZ(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int scn, bool swapBlue) |
void cv::hal::cvtBGRtoXYZ(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, ElemDepth depth, int scn, bool swapBlue) |
void cv::hal::cvtXYZtoBGR(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int dcn, bool swapBlue) |
void cv::hal::cvtXYZtoBGR(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, ElemDepth depth, int dcn, bool swapBlue) |
void cv::hal::cvtBGRtoHSV(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int scn, bool swapBlue, bool isFullRange, bool isHSV) |
void cv::hal::cvtBGRtoHSV(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, ElemDepth depth, int scn, bool swapBlue, bool isFullRange, bool isHSV) |
void cv::hal::cvtHSVtoBGR(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int dcn, bool swapBlue, bool isFullRange, bool isHSV) |
void cv::hal::cvtHSVtoBGR(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, ElemDepth depth, int dcn, bool swapBlue, bool isFullRange, bool isHSV) |
void cv::hal::cvtBGRtoLab(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int scn, bool swapBlue, bool isLab, bool srgb) |
void cv::hal::cvtBGRtoLab(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, ElemDepth depth, int scn, bool swapBlue, bool isLab, bool srgb) |
void cv::hal::cvtLabtoBGR(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int dcn, bool swapBlue, bool isLab, bool srgb) |
void cv::hal::cvtLabtoBGR(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, ElemDepth depth, int dcn, bool swapBlue, bool isLab, bool srgb) |
void cv::hal::integral(int depth, int sdepth, int sqdepth, const uchar* src, size_t srcstep, uchar* sum, size_t sumstep, uchar* sqsum, size_t sqsumstep, uchar* tilted, size_t tstep, int width, int height, int cn) |
void cv::hal::integral(ElemDepth depth, ElemDepth sdepth, int sqdepth, const uchar* src, size_t srcstep, uchar* sum, size_t sumstep, uchar* sqsum, size_t sqsumstep, uchar* tilted, size_t tstep, int width, int height, int cn) |
Mat cv::dnn::blobFromImage(Mat image, double scalefactor = 1::0, const Size &size = Size(), const Scalar &mean = Scalar(), bool swapRB = true, bool crop = true, int ddepth = CV_32F) |
Mat cv::dnn::blobFromImage(Mat image, double scalefactor = 1::0, const Size &size = Size(), const Scalar &mean = Scalar(), bool swapRB = true, bool crop = true, ElemDepth ddepth = CV_32F) |
void cv::dnn::blobFromImage(Mat image, Mat &blob, double scalefactor = 1::0, const Size &size = Size(), const Scalar &mean = Scalar(), bool swapRB = true, bool crop = true, int ddepth = CV_32F) |
void cv::dnn::blobFromImage(Mat image, Mat &blob, double scalefactor = 1::0, const Size &size = Size(), const Scalar &mean = Scalar(), bool swapRB = true, bool crop = true, ElemDepth ddepth = CV_32F) |
Mat cv::dnn::blobFromImages(vector_Mat images, double scalefactor = 1::0, Size size = Size(), const Scalar &mean = Scalar(), bool swapRB = true, bool crop = true, int ddepth = CV_32F) |
Mat cv::dnn::blobFromImages(vector_Mat images, double scalefactor = 1::0, Size size = Size(), const Scalar &mean = Scalar(), bool swapRB = true, bool crop = true, ElemDepth ddepth = CV_32F) |
void cv::dnn::blobFromImages(vector_Mat images, Mat &blob, double scalefactor = 1::0, Size size = Size(), const Scalar &mean = Scalar(), bool swapRB = true, bool crop = true, int ddepth = CV_32F) |
void cv::dnn::blobFromImages(vector_Mat images, Mat &blob, double scalefactor = 1::0, Size size = Size(), const Scalar &mean = Scalar(), bool swapRB = true, bool crop = true, ElemDepth ddepth = CV_32F) |
int cv::Feature2D::descriptorType() |
ElemType cv::Feature2D::descriptorType() |
int cv::BOWImgDescriptorExtractor::descriptorType() |
ElemType cv::BOWImgDescriptorExtractor::descriptorType() |
void cv::reprojectImageTo3D(Mat disparity, Mat &_3dImage, Mat Q, bool handleMissingValues = false, int ddepth = -1) |
void cv::reprojectImageTo3D(Mat disparity, Mat &_3dImage, Mat Q, bool handleMissingValues = false, ElemDepth ddepth = CV_DEPTH_UNSPECIFIED) |
void cv::fisheye::initUndistortRectifyMap(Mat K, Mat D, Mat R, Mat P, const Size &size, int m1type, Mat &map1, Mat &map2) |
void cv::fisheye::initUndistortRectifyMap(Mat K, Mat D, Mat R, Mat P, const Size &size, ElemType m1type, Mat &map1, Mat &map2) |
void cv::omnidir::initUndistortRectifyMap(Mat K, Mat D, Mat xi, Mat R, Mat P, const Size &size, int mltype, Mat &map1, Mat &map2, int flags) |
void cv::omnidir::initUndistortRectifyMap(Mat K, Mat D, Mat xi, Mat R, Mat P, const Size &size, ElemType mltype, Mat &map1, Mat &map2, int flags) |
Ptr<RgbdNormals> cv::rgbd::RgbdNormals::create(int rows, int cols, int depth, Mat K, int window_size = 5, int method = RgbdNormals::RGBD_NORMALS_METHOD_FALS) |
Ptr<RgbdNormals> cv::rgbd::RgbdNormals::create(int rows, int cols, ElemDepth depth, Mat K, int window_size = 5, int method = RgbdNormals::RGBD_NORMALS_METHOD_FALS) |
void cv::rgbd::RgbdNormals::setDepth(int val) |
void cv::rgbd::RgbdNormals::setDepth(ElemDepth val) |
Ptr<DepthCleaner> cv::rgbd::DepthCleaner::create(int depth, int window_size = 5, int method = DepthCleaner::DEPTH_CLEANER_NIL) |
Ptr<DepthCleaner> cv::rgbd::DepthCleaner::create(ElemDepth depth, int window_size = 5, int method = DepthCleaner::DEPTH_CLEANER_NIL) |
void cv::rgbd::DepthCleaner::setDepth(int val) |
void cv::rgbd::DepthCleaner::setDepth(ElemDepth val) |
void cv::rgbd::rescaleDepth(Mat in, int depth, Mat &out) |
void cv::rgbd::rescaleDepth(Mat in, ElemDepth depth, Mat &out) |
cv::KalmanFilter(int dynamParams, int measureParams, int controlParams = 0, int type = CV_32F) |
cv::KalmanFilter(int dynamParams, int measureParams, int controlParams = 0, ElemType type = CV_32FC1) |
void cv::ximgproc::DTFilter::filter(Mat src, Mat &dst, int dDepth = -1) |
void cv::ximgproc::DTFilter::filter(Mat src, Mat &dst, ElemDepth dDepth = CV_DEPTH_UNSPECIFIED) |
void cv::ximgproc::GuidedFilter::filter(Mat src, Mat &dst, int dDepth = -1) |
void cv::ximgproc::GuidedFilter::filter(Mat src, Mat &dst, ElemDepth dDepth = CV_DEPTH_UNSPECIFIED) |
void cv::ximgproc::guidedFilter(Mat guide, Mat src, Mat &dst, int radius, double eps, int dDepth = -1) |
void cv::ximgproc::guidedFilter(Mat guide, Mat src, Mat &dst, int radius, double eps, ElemDepth dDepth = CV_DEPTH_UNSPECIFIED) |
Ptr<RidgeDetectionFilter> cv::ximgproc::RidgeDetectionFilter::create(int ddepth = CV_32FC1, int dx = 1, int dy = 1, int ksize = 3, int out_dtype = CV_8UC1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT) |
Ptr<RidgeDetectionFilter> cv::ximgproc::RidgeDetectionFilter::create(ElemDepth ddepth = CV_32F, int dx = 1, int dy = 1, int ksize = 3, ElemType out_dtype = CV_8UC1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT) |
@alalek I am getting this error on Linux and Mac OS builds:
undefined reference to `cv::traits::Type<cv::Point_<int> >::value
Any idea?
It wants declaration outside of class. "constexpr" doesn't help here (until C++17). "inline static members" is C++17 feature too.
https://en.cppreference.com/w/cpp/language/static:
If a const non-inline (since C++17) static data member or a constexpr static data member (since C++11) is odr-used, a definition at namespace scope is still required, but it cannot have an initializer. This definition is deprecated for constexpr data members (since C++17).
"odr" includes "const ElemType&". For example, from here:
cv::operator | (cv::_InputArray::KindFlag const&, ElemType const&)
IMHO, "const reference" enums parameters should be avoided. Use just "const EnumType".
P.S. It is better to check "Linux Debug" build. Partial fix: https://github.com/alalek/opencv/commit/pr12288_fix_enum_odr
@alalek @vpisarev @hrnr There is a chance I made some serious mistakes in the API.. Kindly be asked to review the new API from the summary table I wrote above as soon as you can, because it would be almost impossible to manage changing it a lot once I start splitting the commits into different PRs with several commits depending on each other.
As for type names, I still plan to change them to MatType and MatDepth after the library passes the compatibility checks, because such types are already utilized in the testing suite.
I guess I have finished the major parts of this PR, and I plan to start writing the overloaded legacy-compatible interface after a few hours break.
@alalek I need your help, please!
I am writing the overloaded legacy API, but I got thousands of x function already defined in object y
errors, which most probably means inline definition at the header file is not going to work. Shall I proceed and move the definition bodies to the corresponding cpp files?
More importantly, the overloaded API causes ambiguity such as in this build. Any idea for a workaround?
@alalek @hrnr @vpisarev
At any rate, I am afraid I will not finish by today, which was the deadline I made for myself.
Thus, if you think the current ambiguity problem is workable in time, then I will give it another day or so, otherwise I can rewrite all the enums as #typedef int EnumName
, thus maintaining optimal compatibility (but not type-safety 😕), and to make the library in a slightly better shape.
What do you think?
Preserving "legacy" API with "int" in my meaning is:
typedef int ElemType;
typedef int ElemDepth;
#define CV_8U 0
#define CV_8S 1
...
This is already done in interface.h.
No need to have both "overloads" with "enum" and "int" in OpenCV binaries.
If users want to use "int" then they should recompile their OpenCV 4.0 copy with disabled __cv_strict_types
definition.
Another "legacy" API compatibility is about using ElemDepth
for ElemType
like:
cv::Mat m(10, 10, CV_32F);
// do not require: cv::Mat m(10, 10, CV_32FC1);
It will be good if we handle the most part of cases from your commit "Refactored code for type-safety".
BTW, Please leave "as is" interfaces for functions like cvCreateMat()
(it is C-API, don't push enums here - there is no way to make helpers-operators)
So, save your commit "Refactored code for type-safety" in a separate branch (for further/separate PR) and remove it from the current patch.
Use unchanged OpenCV code (with CV_32F
instead of CV_32FC1
) as a test ground.
Then start adding overloads to cover massive build problems. Please make this overloads "inline" which just calls "original" method/function.
Rare cases fix inplace (but they should be really rare).
There is no goal to support both ElemType and ElemDepth in all cases.
Below are my proposals for this snippet (from mat.hpp):
#if defined(cv_deprecated_api) && defined(__cv_strict_types) && defined(__cplusplus)
void create(Size sz, int type, int i = -1, bool allowTransposed = false, _OutputArray::DepthMask fixedDepthMask = static_cast<_OutputArray::DepthMask>(0)) const
{
CV_COUNTER_INIT()
CV_DEPRECATED_TYPE_WARNING("type", "int", "ElemType", 1);
CV_COUNTER_INC()
return create(sz, static_cast<ElemType>(type), i, allowTransposed, fixedDepthMask);
}
#endif
1.
&& defined(__cplusplus)
Remove this. Do not touch C-only files.
2.
CV_COUNTER_INIT()
CV_DEPRECATED_TYPE_WARNING("type", "int", "ElemType", 1);
CV_COUNTER_INC()
Perhaps this should be done in other way (compiler warning, instead of runtime). Lets remove this and leave for further changes.
3.
void create(...)
Use "inline": inline void create(...)
4.
int type
Perhaps we don't want to see here "5" instead of CV_32F
/ CV_32FC1
. Even in user code. @vpisarev , Right?
Please use "ElemDepth type" instead to allow CV_32F only.
Completely legacy code which wants "int" should re-compile own OpenCV without __cv_strict_types
and with typedef int ElemType
.
@alalek Even with that, there is still the cases where the user passes -1
for unspecified depth/type. I believe such case will not work unless int
overload is there. Any decision about that?
-1
Usually such params has default "-1" value on the last place and it is not used.
There are some cases where such parameter is not on the last position:
-cv::boxFilter(src_roi, dst_roi, -1, ksize, anchor, normalize, borderType)
+cv::boxFilter(src_roi, dst_roi, CV_DEPTH_UNSPECIFIED, ksize, anchor, normalize, borderType)
There is another type of problem - local type variables which uses 'int'
int type = src.type();
...
dst.create(..., type);
This may require larger changes in user code if there is no "int" overloads.
Usually it is enough using auto type
.
But both cases are rare than "cv::Mat m(10, 10, CV_32F);" problem.
1) I suggest to make 'depth' and 'type' enumerations the same thing, that will help us to avoid unnecessary CV_8U
to CV_8UC1
conversions.
2) CV_DEPTH_UNSPECIFIED
sounds too complex; let's use CV_DEPTH_AUTO
or even better CV_TYPE_AUTO
, as I suggest to combine depth and type into a single enumeration.
At the same time, the newly created mat's may be initialized with type=CV_TYPE_UNDEFINED
, as we discussed with @alalek.
@vpisarev @alalek @mshabunin I am all done with all the testing and verification.
Currently, this PR works as a proof that the mutually-exclusive "Refactor *" PRs not only builds successfully, but they are collectively resolving all warnings (please note the green lights on this PR) even if OPENCV_ENABLE_DEPRECATED_WARNING_ELEMDEPTH_ELEMTYPE_OVERLOAD
is set (which I wish to keep it ON in the farm for code quality - enabled via the last commit)
TESTING... DO NOT MERGE!
Merge with opencv/opencv_contrib#1730 and opencv/opencv_extra#515This pullrequest changes
There are hundreds of unnamed enums, and they are being passed as int in the C++ interface. In order to avoid passing a wrong value, and to maintain good practices, the hope is to name most of these enums, and change the int arguments into the proper enum types wherever possible.
Newly introduced enums
ElemType
for handling the depth and channels of matrix elements (Produced byDataType<T>::type
andtraits::Type<T>::value
)ElemDepth
for handling the depth of matrix elements (Produced byDataDepth<T>::type
andtraits::Depth<T>::value
)MagicFlag
for handling the mixed magic values ofElemType
,AccessFlag
and_InputArray::KindFlag
Flag enums
AccessFlag
forunnamed
enum havingACCESS_READ
as first memberunnamed
enum havingDEFAULT
as first memberMemoryFlag
for UMatData::unnamed
enum havingCOPY_ON_MAP
as first memberKindFlag
for _InputArray::unnamed
enum havingKIND_SHIFT
as first memberMode enums
DescriptorType
for AKAZE::unnamed
enum havingDESCRIPTOR_KAZE_UPRIGHT
as first memberDetectorType
for AgastFeatureDetector::unnamed
enum havingAGAST_5_8
as first memberFeatureType
for CvFeatureParams::unnamed
enum havingHAAR
as first memberDetectorType
for FastFeatureDetector::unnamed
enum havingTYPE_5_8
as first memberMatcherType
for DescriptorMatcher::unnamed
enum havingFLANNBASED
as first memberFormatType
for Formatter::unnamed
enum havingFMT_DEFAULT
as first memberHistogramNormType
for HOGDescriptor::unnamed
enum havingL2Hys
as the only memberunnamed
enum havingnormType
as the only memberunnamed
enum havingnormType
as the only memberunnamed
enum havingnormType
as the only memberunnamed
enum havingnormType
as the only memberunnamed
enum havingMAGIC_MASK
as first memberunnamed
enum havingMAGIC_VAL
as first memberunnamed
enum havingMAGIC_VAL
as first memberunnamed
enum havingMAGIC_MASK
as first memberunnamed
enum havingMAGIC_VAL
as first memberDiffusivityType
for KAZE::unnamed
enum havingDIFF_PM_G1
as first memberScoreType
for ORB::unnamed
enum havingkBytes
as first member, andkBytes
become a static const intunnamed
enum havingINT
as first memberunnamed
enum havingLOCATION_ROW
as first memberunnamed
enum havingDESCR_FORMAT_ROW_BY_ROW
as first memberunnamed
enum havingX_ROW
as first memberNormalizationType
for xfeatures2d::DAISY::unnamed
enum havingNRM_NONE
as first memberunnamed
enum havingNB_SCALES
as first memberDepthMask
for _OutputArray::unnamed
enum havingDEPTH_MASK_8U
as first memberTasks list
unnamed
enum havingCALIB_CB_ADAPTIVE_THRESH
as first memberunnamed
enum havingCALIB_CB_SYMMETRIC_GRID
as first memberunnamed
enum havingCALIB_USE_INTRINSIC_GUESS
as first memberunnamed
enum havingCAP_INTELPERC_DEPTH_GENERATOR
as first memberunnamed
enum havingCAP_INTELPERC_DEPTH_MAP
as first memberunnamed
enum havingCAP_OPENNI_DEPTH_GENERATOR
as first memberunnamed
enum havingCAP_OPENNI_DEPTH_MAP
as first memberunnamed
enum havingCAP_OPENNI_IMAGE_GENERATOR_PRESENT
as first memberunnamed
enum havingCAP_OPENNI_VGA_30HZ
as first memberunnamed
enum havingCAP_PROP_DC1394_OFF
as first memberunnamed
enum havingCAP_PROP_GIGA_FRAME_OFFSET_X
as first memberunnamed
enum havingCAP_PROP_GPHOTO2_PREVIEW
as first memberunnamed
enum havingCAP_PROP_GSTREAMER_QUEUE_LENGTH
as first memberunnamed
enum havingCAP_PROP_IMAGES_BASE
as first memberunnamed
enum havingCAP_PROP_INTELPERC_PROFILE_COUNT
as first memberunnamed
enum havingCAP_PROP_IOS_DEVICE_FOCUS
as first memberunnamed
enum havingCAP_PROP_OPENNI_OUTPUT_MODE
as first memberunnamed
enum havingCAP_PROP_PVAPI_MULTICASTIP
as first memberunnamed
enum havingCAP_PROP_XI_DOWNSAMPLING
as first memberunnamed
enum havingCAP_PVAPI_DECIMATION_OFF
as first memberunnamed
enum havingCAP_PVAPI_FSTRIGMODE_FREERUN
as first memberunnamed
enum havingCAP_PVAPI_PIXELFORMAT_MONO8
as first memberunnamed
enum havingCASCADE_DO_CANNY_PRUNING
as first memberunnamed
enum havingFM_7POINT
as first memberunnamed
enum havingINPAINT_NS
as first memberunnamed
enum havingLDR_SIZE
as first memberunnamed
enum havingLMEDS
as first memberunnamed
enum havingMOTION_TRANSLATION
as first memberunnamed
enum havingNORMAL_CLONE
as first memberunnamed
enum havingOPTFLOW_USE_INITIAL_FLOW
as first memberunnamed
enum havingRECURS_FILTER
as first memberunnamed
enum havingSOLVEPNP_ITERATIVE
as first memberunnamed
enum havingUNIFORM
as first memberunnamed
enum havingPREFILTER_NORMALIZED_RESPONSE
as first memberunnamed
enum havingDISP_SHIFT
as first memberunnamed
enum havingMODE_SGBM
as first memberunnamed
enum havingORIG_RESOL
as first memberunnamed
enum havingNEXT_AROUND_ORG
as first memberunnamed
enum havingPTLOC_ERROR
as first memberunnamed
enum havingMODE_POSITIVE
as first memberunnamed
enum havingMODE_INIT_POS
as first memberunnamed
enum havingRETINA_COLOR_RANDOM
as first memberunnamed
enum havingNO
as first memberunnamed
enum havingNO
as first memberunnamed
enum havingAS_IS
as first memberunnamed
enum havingCALIB_USE_INTRINSIC_GUESS
as first memberunnamed
enum havingLINEAR
as first memberunnamed
enum havingONE_STEP
as first memberunnamed
enum havingDEFAULT
as first memberunnamed
enum havingDEFAULT_NCLUSTERS
as first memberunnamed
enum havingSTART_E_STEP
as first memberunnamed
enum havingPINHOLE
as first memberunnamed
enum havingEXEC_KERNEL
as first memberunnamed
enum havingFP_DENORM
as first memberunnamed
enum havingNO_CACHE
as first memberunnamed
enum havingNO_LOCAL_MEM
as first memberunnamed
enum havingTYPE_DEFAULT
as first memberunnamed
enum havingUNKNOWN_VENDOR
as first memberunnamed
enum havingLOCAL
as first memberunnamed
enum havingCALIB_USE_GUESS
as first memberunnamed
enum havingRECTIFY_PERSPECTIVE
as first memberunnamed
enum havingXYZRGB
as first memberunnamed
enum havingPRESET_ULTRAFAST
as first memberunnamed
enum havingROTATION
as first memberunnamed
enum havingCACHE_SRC
as first memberunnamed
enum havingDECODE_3D_UNDERWORLD
as first memberunnamed
enum havingFTP
as first memberunnamed
enum havingERFILTER_NM_RGBLGrad
as first memberunnamed
enum havingOCR_LEVEL_WORD
as first memberunnamed
enum havingNONE
as first memberunnamed
enum havingLOAD_AUTO
as first memberunnamed
enum havingFRAMES
as first memberCurrent issues
unnamed
enum havingUNDEFINED
as first memberstatic_cast<MagicFlag>()
are utilized now. Proper operators needs to get enabledunnamed
enum havingDEFAULT_NLEVELS
as the only member to to static const int causes some Java test to fail[javac] /build/precommit_android/build/android_test/src/org/opencv/test/objdetect/HOGDescriptorTest.java:204: error: cannot find symbol [javac] assertEquals(HOGDescriptor.DEFAULT_NLEVELS, hog.get_nlevels()); [javac] ^ [javac] symbol: variable DEFAULT_NLEVELS [javac] location: class HOGDescriptor [javac] Note: Some input files use unchecked or unsafe operations. [javac] Note: Recompile with -Xlint:unchecked for details. [javac] 1 error