diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ccad4d03a..e205886355 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,9 @@ if(POLICY CMP0075) cmake_policy(SET CMP0075 NEW) # CMake 3.12+: Include file check macros honor `CMAKE_REQUIRED_LIBRARIES` endif() +if(POLICY CMP0077) + cmake_policy(SET CMP0077 NEW) # CMake 3.13+: option() honors normal variables. +endif() # # Configure OpenCV CMake hooks diff --git a/doc/tutorials/core/file_input_output_with_xml_yml/file_input_output_with_xml_yml.markdown b/doc/tutorials/core/file_input_output_with_xml_yml/file_input_output_with_xml_yml.markdown index e74f770123..b71fbebc41 100644 --- a/doc/tutorials/core/file_input_output_with_xml_yml/file_input_output_with_xml_yml.markdown +++ b/doc/tutorials/core/file_input_output_with_xml_yml/file_input_output_with_xml_yml.markdown @@ -17,7 +17,7 @@ You'll find answers for the following questions: Source code ----------- - +@add_toggle_cpp You can [download this from here ](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp) or find it in the `samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp` of the OpenCV source code @@ -26,13 +26,25 @@ library. Here's a sample code of how to achieve all the stuff enumerated at the goal list. @include cpp/tutorial_code/core/file_input_output/file_input_output.cpp +@end_toggle + +@add_toggle_python +You can [download this from here +](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/core/file_input_output/file_input_output.py) or find it in the +`samples/python/tutorial_code/core/file_input_output/file_input_output.py` of the OpenCV source code +library. + +Here's a sample code of how to achieve all the stuff enumerated at the goal list. + +@include python/tutorial_code/core/file_input_output/file_input_output.py +@end_toggle Explanation ----------- Here we talk only about XML and YAML file inputs. Your output (and its respective input) file may have only one of these extensions and the structure coming from this. They are two kinds of data -structures you may serialize: *mappings* (like the STL map) and *element sequence* (like the STL +structures you may serialize: *mappings* (like the STL map and the Python dictionary) and *element sequence* (like the STL vector). The difference between these is that in a map every element has a unique name through what you may access it. For sequences you need to go through them to query a specific item. @@ -40,12 +52,12 @@ you may access it. For sequences you need to go through them to query a specific and at the end to close it. The XML/YAML data structure in OpenCV is @ref cv::FileStorage . To specify that this structure to which file binds on your hard drive you can use either its constructor or the *open()* function of this: - @code{.cpp} - string filename = "I.xml"; - FileStorage fs(filename, FileStorage::WRITE); - //... - fs.open(filename, FileStorage::READ); - @endcode + @add_toggle_cpp + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp open + @end_toggle + @add_toggle_python + @snippet python/tutorial_code/core/file_input_output/file_input_output.py open + @end_toggle Either one of this you use the second argument is a constant specifying the type of operations you'll be able to on them: WRITE, READ or APPEND. The extension specified in the file name also determinates the output format that will be used. The output may be even compressed if you @@ -53,75 +65,83 @@ you may access it. For sequences you need to go through them to query a specific The file automatically closes when the @ref cv::FileStorage objects is destroyed. However, you may explicitly call for this by using the *release* function: - @code{.cpp} - fs.release(); // explicit close - @endcode --# **Input and Output of text and numbers.** The data structure uses the same \<\< output operator - that the STL library. For outputting any type of data structure we need first to specify its - name. We do this by just simply printing out the name of this. For basic types you may follow - this with the print of the value : - @code{.cpp} - fs << "iterationNr" << 100; - @endcode + @add_toggle_cpp + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp close + @end_toggle + @add_toggle_python + @snippet python/tutorial_code/core/file_input_output/file_input_output.py close + @end_toggle +-# **Input and Output of text and numbers.** In C++, the data structure uses the \<\< output + operator in the STL library. In Python, @ref cv::FileStorage.write() is used instead. For + outputting any type of data structure we need first to specify its name. We do this by just + simply pushing the name of this to the stream in C++. In Python, the first parameter for the + write function is the name. For basic types you may follow this with the print of the value : + @add_toggle_cpp + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp writeNum + @end_toggle + @add_toggle_python + @snippet python/tutorial_code/core/file_input_output/file_input_output.py writeNum + @end_toggle Reading in is a simple addressing (via the [] operator) and casting operation or a read via - the \>\> operator : - @code{.cpp} - int itNr; - fs["iterationNr"] >> itNr; - itNr = (int) fs["iterationNr"]; - @endcode + the \>\> operator. In Python, we address with getNode() and use real() : + @add_toggle_cpp + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp readNum + @end_toggle + @add_toggle_python + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp readNum + @end_toggle -# **Input/Output of OpenCV Data structures.** Well these behave exactly just as the basic C++ - types: - @code{.cpp} - Mat R = Mat_::eye (3, 3), - T = Mat_::zeros(3, 1); - - fs << "R" << R; // Write cv::Mat - fs << "T" << T; - - fs["R"] >> R; // Read cv::Mat - fs["T"] >> T; - @endcode + and Python types: + @add_toggle_cpp + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp iomati + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp iomatw + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp iomat + @end_toggle + @add_toggle_python + @snippet python/tutorial_code/core/file_input_output/file_input_output.py iomati + @snippet python/tutorial_code/core/file_input_output/file_input_output.py iomatw + @snippet python/tutorial_code/core/file_input_output/file_input_output.py iomat + @end_toggle -# **Input/Output of vectors (arrays) and associative maps.** As I mentioned beforehand, we can output maps and sequences (array, vector) too. Again we first print the name of the variable and then we have to specify if our output is either a sequence or map. For sequence before the first element print the "[" character and after the last one the "]" - character: - @code{.cpp} - fs << "strings" << "["; // text - string sequence - fs << "image1.jpg" << "Awesomeness" << "baboon.jpg"; - fs << "]"; // close sequence - @endcode + character. With Python, the "]" character could be written with the name of the sequence or + the last element of the sequence depending on the number of elements: + @add_toggle_cpp + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp writeStr + @end_toggle + @add_toggle_python + @snippet python/tutorial_code/core/file_input_output/file_input_output.py writeStr + @end_toggle For maps the drill is the same however now we use the "{" and "}" delimiter characters: - @code{.cpp} - fs << "Mapping"; // text - mapping - fs << "{" << "One" << 1; - fs << "Two" << 2 << "}"; - @endcode + @add_toggle_cpp + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp writeMap + @end_toggle + @add_toggle_python + @snippet python/tutorial_code/core/file_input_output/file_input_output.py writeMap + @end_toggle To read from these we use the @ref cv::FileNode and the @ref cv::FileNodeIterator data - structures. The [] operator of the @ref cv::FileStorage class returns a @ref cv::FileNode data + structures. The [] operator of the @ref cv::FileStorage class (or the getNode() function in Python) returns a @ref cv::FileNode data type. If the node is sequential we can use the @ref cv::FileNodeIterator to iterate through the - items: - @code{.cpp} - FileNode n = fs["strings"]; // Read string sequence - Get node - if (n.type() != FileNode::SEQ) - { - cerr << "strings is not a sequence! FAIL" << endl; - return 1; - } - - FileNodeIterator it = n.begin(), it_end = n.end(); // Go through the node - for (; it != it_end; ++it) - cout << (string)*it << endl; - @endcode - For maps you can use the [] operator again to access the given item (or the \>\> operator too): - @code{.cpp} - n = fs["Mapping"]; // Read mappings from a sequence - cout << "Two " << (int)(n["Two"]) << "; "; - cout << "One " << (int)(n["One"]) << endl << endl; - @endcode + items. In Python, the at() function can be used to address elements of the sequence and the + size() function returns the length of the sequence: + @add_toggle_cpp + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp readStr + @end_toggle + @add_toggle_python + @snippet python/tutorial_code/core/file_input_output/file_input_output.py readStr + @end_toggle + For maps you can use the [] operator (at() function in Python) again to access the given item (or the \>\> operator too): + @add_toggle_cpp + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp readMap + @end_toggle + @add_toggle_python + @snippet python/tutorial_code/core/file_input_output/file_input_output.py readMap + @end_toggle -# **Read and write your own data structures.** Suppose you have a data structure such as: + @add_toggle_cpp @code{.cpp} class MyData { @@ -133,53 +153,52 @@ you may access it. For sequences you need to go through them to query a specific string id; }; @endcode - It's possible to serialize this through the OpenCV I/O XML/YAML interface (just as in case of - the OpenCV data structures) by adding a read and a write function inside and outside of your - class. For the inside part: - @code{.cpp} - void write(FileStorage& fs) const //Write serialization for this class - { - fs << "{" << "A" << A << "X" << X << "id" << id << "}"; - } - - void read(const FileNode& node) //Read serialization for this class - { - A = (int)node["A"]; - X = (double)node["X"]; - id = (string)node["id"]; - } - @endcode - Then you need to add the following functions definitions outside the class: - @code{.cpp} - void write(FileStorage& fs, const std::string&, const MyData& x) - { - x.write(fs); - } - - void read(const FileNode& node, MyData& x, const MyData& default_value = MyData()) - { - if(node.empty()) - x = default_value; - else - x.read(node); - } + @end_toggle + @add_toggle_python + @code{.py} + class MyData: + def __init__(self): + self.A = self.X = 0 + self.name = '' @endcode + @end_toggle + In C++, it's possible to serialize this through the OpenCV I/O XML/YAML interface (just as + in case of the OpenCV data structures) by adding a read and a write function inside and outside of your + class. In Python, you can get close to this by implementing a read and write function inside + the class. For the inside part: + @add_toggle_cpp + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp inside + @end_toggle + @add_toggle_python + @snippet python/tutorial_code/core/file_input_output/file_input_output.py inside + @end_toggle + @add_toggle_cpp + In C++, you need to add the following functions definitions outside the class: + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp outside + @end_toggle Here you can observe that in the read section we defined what happens if the user tries to read a non-existing node. In this case we just return the default initialization value, however a more verbose solution would be to return for instance a minus one value for an object ID. Once you added these four functions use the \>\> operator for write and the \<\< operator for - read: - @code{.cpp} - MyData m(1); - fs << "MyData" << m; // your own data structures - fs["MyData"] >> m; // Read your own structure_ - @endcode + read (or the defined input/output functions for Python): + @add_toggle_cpp + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp customIOi + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp customIOw + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp customIO + @end_toggle + @add_toggle_python + @snippet python/tutorial_code/core/file_input_output/file_input_output.py customIOi + @snippet python/tutorial_code/core/file_input_output/file_input_output.py customIOw + @snippet python/tutorial_code/core/file_input_output/file_input_output.py customIO + @end_toggle Or to try out reading a non-existing read: - @code{.cpp} - fs["NonExisting"] >> m; // Do not add a fs << "NonExisting" << m command for this to work - cout << endl << "NonExisting = " << endl << m << endl; - @endcode + @add_toggle_cpp + @snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp nonexist + @end_toggle + @add_toggle_python + @snippet python/tutorial_code/core/file_input_output/file_input_output.py nonexist + @end_toggle Result ------ diff --git a/doc/tutorials/video/meanshift/meanshift.markdown b/doc/tutorials/video/meanshift/meanshift.markdown index c0e745824e..c51b8fc181 100644 --- a/doc/tutorials/video/meanshift/meanshift.markdown +++ b/doc/tutorials/video/meanshift/meanshift.markdown @@ -57,6 +57,14 @@ low light, low light values are discarded using **cv.inRange()** function. @include samples/python/tutorial_code/video/meanshift/meanshift.py @end_toggle +@add_toggle_java +- **Downloadable code**: Click + [here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/video/meanshift/MeanshiftDemo.java) + +- **Code at glance:** + @include samples/java/tutorial_code/video/meanshift/MeanshiftDemo.java +@end_toggle + Three frames in a video I used is given below: ![image](images/meanshift_result.jpg) @@ -98,6 +106,14 @@ parameters (used to be passed as search window in next iteration). See the code @include samples/python/tutorial_code/video/meanshift/camshift.py @end_toggle +@add_toggle_java +- **Downloadable code**: Click + [here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/video/meanshift/CamshiftDemo.java) + +- **Code at glance:** + @include samples/java/tutorial_code/video/meanshift/CamshiftDemo.java +@end_toggle + Three frames of the result is shown below: ![image](images/camshift_result.jpg) diff --git a/doc/tutorials/video/optical_flow/optical_flow.markdown b/doc/tutorials/video/optical_flow/optical_flow.markdown index d4809761bd..8dc86d9a7e 100644 --- a/doc/tutorials/video/optical_flow/optical_flow.markdown +++ b/doc/tutorials/video/optical_flow/optical_flow.markdown @@ -109,6 +109,15 @@ below: @include samples/python/tutorial_code/video/optical_flow/optical_flow.py @end_toggle + +@add_toggle_java +- **Downloadable code**: Click + [here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/video/optical_flow/OpticalFlowDemo.java) + +- **Code at glance:** + @include samples/java/tutorial_code/video/optical_flow/OpticalFlowDemo.java +@end_toggle + (This code doesn't check how correct are the next keypoints. So even if any feature point disappears in image, there is a chance that optical flow finds the next point which may look close to it. So actually for a robust tracking, corner points should be detected in particular intervals. OpenCV @@ -151,6 +160,15 @@ corresponds to Value plane. See the code below: @end_toggle +@add_toggle_java +- **Downloadable code**: Click + [here](https://github.com/opencv/opencv/tree/master/samples/java/tutorial_code/video/optical_flow/OpticalFlowDenseDemo.java) + +- **Code at glance:** + @include samples/java/tutorial_code/video/optical_flow/OpticalFlowDenseDemo.java +@end_toggle + + See the result below: ![image](images/opticalfb.jpg) diff --git a/doc/tutorials/video/table_of_content_video.markdown b/doc/tutorials/video/table_of_content_video.markdown index 92a5315355..1a80f716da 100644 --- a/doc/tutorials/video/table_of_content_video.markdown +++ b/doc/tutorials/video/table_of_content_video.markdown @@ -17,12 +17,12 @@ tracking and foreground extractions. - @subpage tutorial_meanshift - *Languages:* C++, Python + *Languages:* C++, Java, Python Learn how to use the Meanshift and Camshift algorithms to track objects in videos. - @subpage tutorial_optical_flow - *Languages:* C++, Python + *Languages:* C++, Java, Python We will learn how to use optical flow methods to track sparse features or to create a dense representation. diff --git a/modules/core/include/opencv2/core/hal/intrin.hpp b/modules/core/include/opencv2/core/hal/intrin.hpp index 5a105a7a41..52f6b5d552 100644 --- a/modules/core/include/opencv2/core/hal/intrin.hpp +++ b/modules/core/include/opencv2/core/hal/intrin.hpp @@ -99,6 +99,7 @@ enum StoreMode } +// TODO FIXIT: Don't use "God" traits. Split on separate cases. template struct V_TypeTraits { }; @@ -130,21 +131,51 @@ template struct V_TypeTraits } \ } +#define CV_INTRIN_DEF_TYPE_TRAITS_NO_Q_TYPE(type, int_type_, uint_type_, abs_type_, w_type_, sum_type_, nlanes128_) \ + template<> struct V_TypeTraits \ + { \ + typedef type value_type; \ + typedef int_type_ int_type; \ + typedef abs_type_ abs_type; \ + typedef uint_type_ uint_type; \ + typedef w_type_ w_type; \ + typedef sum_type_ sum_type; \ + enum { nlanes128 = nlanes128_ }; \ + \ + static inline int_type reinterpret_int(type x) \ + { \ + union { type l; int_type i; } v; \ + v.l = x; \ + return v.i; \ + } \ + \ + static inline type reinterpret_from_int(int_type x) \ + { \ + union { type l; int_type i; } v; \ + v.i = x; \ + return v.l; \ + } \ + } + CV_INTRIN_DEF_TYPE_TRAITS(uchar, schar, uchar, uchar, ushort, unsigned, unsigned, 16); CV_INTRIN_DEF_TYPE_TRAITS(schar, schar, uchar, uchar, short, int, int, 16); CV_INTRIN_DEF_TYPE_TRAITS(ushort, short, ushort, ushort, unsigned, uint64, unsigned, 8); CV_INTRIN_DEF_TYPE_TRAITS(short, short, ushort, ushort, int, int64, int, 8); -CV_INTRIN_DEF_TYPE_TRAITS(unsigned, int, unsigned, unsigned, uint64, void, unsigned, 4); -CV_INTRIN_DEF_TYPE_TRAITS(int, int, unsigned, unsigned, int64, void, int, 4); -CV_INTRIN_DEF_TYPE_TRAITS(float, int, unsigned, float, double, void, float, 4); -CV_INTRIN_DEF_TYPE_TRAITS(uint64, int64, uint64, uint64, void, void, uint64, 2); -CV_INTRIN_DEF_TYPE_TRAITS(int64, int64, uint64, uint64, void, void, int64, 2); -CV_INTRIN_DEF_TYPE_TRAITS(double, int64, uint64, double, void, void, double, 2); +CV_INTRIN_DEF_TYPE_TRAITS_NO_Q_TYPE(unsigned, int, unsigned, unsigned, uint64, unsigned, 4); +CV_INTRIN_DEF_TYPE_TRAITS_NO_Q_TYPE(int, int, unsigned, unsigned, int64, int, 4); +CV_INTRIN_DEF_TYPE_TRAITS_NO_Q_TYPE(float, int, unsigned, float, double, float, 4); +CV_INTRIN_DEF_TYPE_TRAITS_NO_Q_TYPE(uint64, int64, uint64, uint64, void, uint64, 2); +CV_INTRIN_DEF_TYPE_TRAITS_NO_Q_TYPE(int64, int64, uint64, uint64, void, int64, 2); +CV_INTRIN_DEF_TYPE_TRAITS_NO_Q_TYPE(double, int64, uint64, double, void, double, 2); #ifndef CV_DOXYGEN #ifndef CV_CPU_OPTIMIZATION_HAL_NAMESPACE -#ifdef CV_CPU_DISPATCH_MODE +#ifdef CV_FORCE_SIMD128_CPP + #define CV_CPU_OPTIMIZATION_HAL_NAMESPACE hal_EMULATOR_CPP + #define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN namespace hal_EMULATOR_CPP { + #define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END } +#elif defined(CV_CPU_DISPATCH_MODE) #define CV_CPU_OPTIMIZATION_HAL_NAMESPACE __CV_CAT(hal_, CV_CPU_DISPATCH_MODE) #define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN namespace __CV_CAT(hal_, CV_CPU_DISPATCH_MODE) { #define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END } @@ -197,7 +228,6 @@ using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE; #else -#define CV_SIMD128_CPP 1 #include "opencv2/core/hal/intrin_cpp.hpp" #endif @@ -242,6 +272,10 @@ CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN #define CV_SIMD128 0 #endif +#ifndef CV_SIMD128_CPP +#define CV_SIMD128_CPP 0 +#endif + #ifndef CV_SIMD128_64F #define CV_SIMD128_64F 0 #endif @@ -346,7 +380,7 @@ template struct V_RegTraits CV_DEF_REG_TRAITS(v, v_int16x8, short, s16, v_uint16x8, v_int32x4, v_int64x2, v_int16x8, void); CV_DEF_REG_TRAITS(v, v_uint32x4, unsigned, u32, v_uint32x4, v_uint64x2, void, v_int32x4, void); CV_DEF_REG_TRAITS(v, v_int32x4, int, s32, v_uint32x4, v_int64x2, void, v_int32x4, void); -#if CV_SIMD128_64F +#if CV_SIMD128_64F || CV_SIMD128_CPP CV_DEF_REG_TRAITS(v, v_float32x4, float, f32, v_float32x4, v_float64x2, void, v_int32x4, v_int32x4); #else CV_DEF_REG_TRAITS(v, v_float32x4, float, f32, v_float32x4, void, void, v_int32x4, v_int32x4); @@ -433,7 +467,11 @@ namespace CV__SIMD_NAMESPACE { } // namespace using namespace CV__SIMD_NAMESPACE; #elif (CV_SIMD128 || CV_SIMD128_CPP) && (!defined(CV__SIMD_FORCE_WIDTH) || CV__SIMD_FORCE_WIDTH == 128) +#if defined CV_SIMD128_CPP +#define CV__SIMD_NAMESPACE simd128_cpp +#else #define CV__SIMD_NAMESPACE simd128 +#endif namespace CV__SIMD_NAMESPACE { #define CV_SIMD CV_SIMD128 #define CV_SIMD_64F CV_SIMD128_64F diff --git a/modules/core/include/opencv2/core/hal/intrin_cpp.hpp b/modules/core/include/opencv2/core/hal/intrin_cpp.hpp index 15ae380e65..d9719b7fa0 100644 --- a/modules/core/include/opencv2/core/hal/intrin_cpp.hpp +++ b/modules/core/include/opencv2/core/hal/intrin_cpp.hpp @@ -50,6 +50,14 @@ #include #include "opencv2/core/saturate.hpp" +//! @cond IGNORED +#define CV_SIMD128_CPP 1 +#if defined(CV_FORCE_SIMD128_CPP) || defined(CV_DOXYGEN) +#define CV_SIMD128 1 +#define CV_SIMD128_64F 1 +#endif +//! @endcond + namespace cv { @@ -135,7 +143,7 @@ Element-wise binary and unary operations. @ref v_shl, @ref v_shr - Bitwise logic: -@ref operator&(const v_reg &a, const v_reg &b) "&", +@ref operator &(const v_reg &a, const v_reg &b) "&", @ref operator |(const v_reg &a, const v_reg &b) "|", @ref operator ^(const v_reg &a, const v_reg &b) "^", @ref operator ~(const v_reg &a) "~" @@ -402,50 +410,102 @@ typedef v_reg v_uint64x2; /** @brief Two 64-bit signed integer values */ typedef v_reg v_int64x2; -//! @brief Helper macro -//! @ingroup core_hal_intrin_impl -#define OPENCV_HAL_IMPL_BIN_OP(bin_op) \ -template inline v_reg<_Tp, n> \ - operator bin_op (const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ -{ \ - v_reg<_Tp, n> c; \ - for( int i = 0; i < n; i++ ) \ - c.s[i] = saturate_cast<_Tp>(a.s[i] bin_op b.s[i]); \ - return c; \ -} \ -template inline v_reg<_Tp, n>& \ - operator bin_op##= (v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ -{ \ - for( int i = 0; i < n; i++ ) \ - a.s[i] = saturate_cast<_Tp>(a.s[i] bin_op b.s[i]); \ - return a; \ -} - /** @brief Add values For all types. */ -OPENCV_HAL_IMPL_BIN_OP(+) +template CV_INLINE v_reg<_Tp, n> operator+(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); +template CV_INLINE v_reg<_Tp, n>& operator+=(v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); /** @brief Subtract values For all types. */ -OPENCV_HAL_IMPL_BIN_OP(-) +template CV_INLINE v_reg<_Tp, n> operator-(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); +template CV_INLINE v_reg<_Tp, n>& operator-=(v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); /** @brief Multiply values For 16- and 32-bit integer types and floating types. */ -OPENCV_HAL_IMPL_BIN_OP(*) +template CV_INLINE v_reg<_Tp, n> operator*(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); +template CV_INLINE v_reg<_Tp, n>& operator*=(v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); /** @brief Divide values For floating types only. */ -OPENCV_HAL_IMPL_BIN_OP(/) +template CV_INLINE v_reg<_Tp, n> operator/(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); +template CV_INLINE v_reg<_Tp, n>& operator/=(v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); -//! @brief Helper macro -//! @ingroup core_hal_intrin_impl -#define OPENCV_HAL_IMPL_BIT_OP(bit_op) \ -template inline v_reg<_Tp, n> operator bit_op \ - (const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ + +/** @brief Bitwise AND + +Only for integer types. */ +template CV_INLINE v_reg<_Tp, n> operator&(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); +template CV_INLINE v_reg<_Tp, n>& operator&=(v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); + +/** @brief Bitwise OR + +Only for integer types. */ +template CV_INLINE v_reg<_Tp, n> operator|(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); +template CV_INLINE v_reg<_Tp, n>& operator|=(v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); + +/** @brief Bitwise XOR + +Only for integer types.*/ +template CV_INLINE v_reg<_Tp, n> operator^(const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); +template CV_INLINE v_reg<_Tp, n>& operator^=(v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b); + +/** @brief Bitwise NOT + +Only for integer types.*/ +template CV_INLINE v_reg<_Tp, n> operator~(const v_reg<_Tp, n>& a); + + +#ifndef CV_DOXYGEN + +#define CV__HAL_INTRIN_EXPAND_WITH_INTEGER_TYPES(macro_name, ...) \ +__CV_EXPAND(macro_name(uchar, __VA_ARGS__)) \ +__CV_EXPAND(macro_name(schar, __VA_ARGS__)) \ +__CV_EXPAND(macro_name(ushort, __VA_ARGS__)) \ +__CV_EXPAND(macro_name(short, __VA_ARGS__)) \ +__CV_EXPAND(macro_name(unsigned, __VA_ARGS__)) \ +__CV_EXPAND(macro_name(int, __VA_ARGS__)) \ +__CV_EXPAND(macro_name(uint64, __VA_ARGS__)) \ +__CV_EXPAND(macro_name(int64, __VA_ARGS__)) \ + +#define CV__HAL_INTRIN_EXPAND_WITH_FP_TYPES(macro_name, ...) \ +__CV_EXPAND(macro_name(float, __VA_ARGS__)) \ +__CV_EXPAND(macro_name(double, __VA_ARGS__)) \ + +#define CV__HAL_INTRIN_EXPAND_WITH_ALL_TYPES(macro_name, ...) \ +CV__HAL_INTRIN_EXPAND_WITH_INTEGER_TYPES(macro_name, __VA_ARGS__) \ +CV__HAL_INTRIN_EXPAND_WITH_FP_TYPES(macro_name, __VA_ARGS__) \ + +#define CV__HAL_INTRIN_IMPL_BIN_OP_(_Tp, bin_op) \ +template inline \ +v_reg<_Tp, n> operator bin_op (const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + v_reg<_Tp, n> c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = saturate_cast<_Tp>(a.s[i] bin_op b.s[i]); \ + return c; \ +} \ +template inline \ +v_reg<_Tp, n>& operator bin_op##= (v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +{ \ + for( int i = 0; i < n; i++ ) \ + a.s[i] = saturate_cast<_Tp>(a.s[i] bin_op b.s[i]); \ + return a; \ +} + +#define CV__HAL_INTRIN_IMPL_BIN_OP(bin_op) CV__HAL_INTRIN_EXPAND_WITH_ALL_TYPES(CV__HAL_INTRIN_IMPL_BIN_OP_, bin_op) + +CV__HAL_INTRIN_IMPL_BIN_OP(+) +CV__HAL_INTRIN_IMPL_BIN_OP(-) +CV__HAL_INTRIN_IMPL_BIN_OP(*) +CV__HAL_INTRIN_EXPAND_WITH_FP_TYPES(CV__HAL_INTRIN_IMPL_BIN_OP_, /) + +#define CV__HAL_INTRIN_IMPL_BIT_OP_(_Tp, bit_op) \ +template CV_INLINE \ +v_reg<_Tp, n> operator bit_op (const v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ { \ v_reg<_Tp, n> c; \ typedef typename V_TypeTraits<_Tp>::int_type itype; \ @@ -454,8 +514,8 @@ template inline v_reg<_Tp, n> operator bit_op \ V_TypeTraits<_Tp>::reinterpret_int(b.s[i]))); \ return c; \ } \ -template inline v_reg<_Tp, n>& operator \ - bit_op##= (v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ +template CV_INLINE \ +v_reg<_Tp, n>& operator bit_op##= (v_reg<_Tp, n>& a, const v_reg<_Tp, n>& b) \ { \ typedef typename V_TypeTraits<_Tp>::int_type itype; \ for( int i = 0; i < n; i++ ) \ @@ -464,33 +524,29 @@ template inline v_reg<_Tp, n>& operator \ return a; \ } -/** @brief Bitwise AND +#define CV__HAL_INTRIN_IMPL_BIT_OP(bit_op) \ +CV__HAL_INTRIN_EXPAND_WITH_INTEGER_TYPES(CV__HAL_INTRIN_IMPL_BIT_OP_, bit_op) \ +CV__HAL_INTRIN_EXPAND_WITH_FP_TYPES(CV__HAL_INTRIN_IMPL_BIT_OP_, bit_op) /* TODO: FIXIT remove this after masks refactoring */ -Only for integer types. */ -OPENCV_HAL_IMPL_BIT_OP(&) -/** @brief Bitwise OR - -Only for integer types. */ -OPENCV_HAL_IMPL_BIT_OP(|) +CV__HAL_INTRIN_IMPL_BIT_OP(&) +CV__HAL_INTRIN_IMPL_BIT_OP(|) +CV__HAL_INTRIN_IMPL_BIT_OP(^) -/** @brief Bitwise XOR +#define CV__HAL_INTRIN_IMPL_BITWISE_NOT_(_Tp, dummy) \ +template CV_INLINE \ +v_reg<_Tp, n> operator ~ (const v_reg<_Tp, n>& a) \ +{ \ + v_reg<_Tp, n> c; \ + for( int i = 0; i < n; i++ ) \ + c.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int(~V_TypeTraits<_Tp>::reinterpret_int(a.s[i])); \ + return c; \ +} \ -Only for integer types.*/ -OPENCV_HAL_IMPL_BIT_OP(^) +CV__HAL_INTRIN_EXPAND_WITH_INTEGER_TYPES(CV__HAL_INTRIN_IMPL_BITWISE_NOT_, ~) -/** @brief Bitwise NOT +#endif // !CV_DOXYGEN -Only for integer types.*/ -template inline v_reg<_Tp, n> operator ~ (const v_reg<_Tp, n>& a) -{ - v_reg<_Tp, n> c; - for( int i = 0; i < n; i++ ) - { - c.s[i] = V_TypeTraits<_Tp>::reinterpret_from_int(~V_TypeTraits<_Tp>::reinterpret_int(a.s[i])); - } - return c; -} //! @brief Helper macro //! @ingroup core_hal_intrin_impl @@ -503,6 +559,27 @@ template inline v_reg<_Tp2, n> func(const v_reg<_Tp, n>& a) return c; \ } +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl +#define OPENCV_HAL_IMPL_MATH_FUNC_FLOAT(func, cfunc) \ +inline v_reg func(const v_reg& a) \ +{ \ + v_reg c; \ + for( int i = 0; i < 4; i++ ) \ + c.s[i] = cfunc(a.s[i]); \ + return c; \ +} \ +inline v_reg func(const v_reg& a) \ +{ \ + v_reg c; \ + for( int i = 0; i < 2; i++ ) \ + { \ + c.s[i] = cfunc(a.s[i]); \ + c.s[i + 2] = 0; \ + } \ + return c; \ +} + /** @brief Square root of elements Only for floating point types.*/ @@ -524,22 +601,22 @@ OPENCV_HAL_IMPL_MATH_FUNC(v_abs, (typename V_TypeTraits<_Tp>::abs_type)std::abs, /** @brief Round elements Only for floating point types.*/ -OPENCV_HAL_IMPL_MATH_FUNC(v_round, cvRound, int) +OPENCV_HAL_IMPL_MATH_FUNC_FLOAT(v_round, cvRound) /** @brief Floor elements Only for floating point types.*/ -OPENCV_HAL_IMPL_MATH_FUNC(v_floor, cvFloor, int) +OPENCV_HAL_IMPL_MATH_FUNC_FLOAT(v_floor, cvFloor) /** @brief Ceil elements Only for floating point types.*/ -OPENCV_HAL_IMPL_MATH_FUNC(v_ceil, cvCeil, int) +OPENCV_HAL_IMPL_MATH_FUNC_FLOAT(v_ceil, cvCeil) /** @brief Truncate elements Only for floating point types.*/ -OPENCV_HAL_IMPL_MATH_FUNC(v_trunc, int, int) +OPENCV_HAL_IMPL_MATH_FUNC_FLOAT(v_trunc, int) //! @brief Helper macro //! @ingroup core_hal_intrin_impl @@ -1083,9 +1160,8 @@ OPENCV_HAL_IMPL_SHIFT_OP(<< ) For 16-, 32- and 64-bit integer values. */ OPENCV_HAL_IMPL_SHIFT_OP(>> ) -/** @brief Element shift left among vector - -For all type */ +//! @brief Helper macro +//! @ingroup core_hal_intrin_impl #define OPENCV_HAL_IMPL_ROTATE_SHIFT_OP(suffix,opA,opB) \ template inline v_reg<_Tp, n> v_rotate_##suffix(const v_reg<_Tp, n>& a) \ { \ @@ -1127,7 +1203,14 @@ template inline v_reg<_Tp, n> v_rotate_##suffix(co return c; \ } +/** @brief Element shift left among vector + +For all type */ OPENCV_HAL_IMPL_ROTATE_SHIFT_OP(left, -, +) + +/** @brief Element shift right among vector + +For all type */ OPENCV_HAL_IMPL_ROTATE_SHIFT_OP(right, +, -) /** @brief Sum packed values @@ -1389,6 +1472,7 @@ similar to cv::v_load, but source memory block should be aligned (to 16-byte bou template inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_load_aligned(const _Tp* ptr) { + CV_Assert(isAligned::nlanes128>)>(ptr)); return v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128>(ptr); } @@ -1620,6 +1704,12 @@ inline void v_store(_Tp* ptr, const v_reg<_Tp, n>& a) ptr[i] = a.s[i]; } +template +inline void v_store(_Tp* ptr, const v_reg<_Tp, n>& a, hal::StoreMode /*mode*/) +{ + v_store(ptr, a); +} + /** @brief Store data to memory (lower half) Store lower half of register contents to memory. @@ -1659,22 +1749,22 @@ Pointer __should__ be aligned by 16-byte boundary. */ template inline void v_store_aligned(_Tp* ptr, const v_reg<_Tp, n>& a) { - for( int i = 0; i < n; i++ ) - ptr[i] = a.s[i]; + CV_Assert(isAligned)>(ptr)); + v_store(ptr, a); } template inline void v_store_aligned_nocache(_Tp* ptr, const v_reg<_Tp, n>& a) { - for( int i = 0; i < n; i++ ) - ptr[i] = a.s[i]; + CV_Assert(isAligned)>(ptr)); + v_store(ptr, a); } template inline void v_store_aligned(_Tp* ptr, const v_reg<_Tp, n>& a, hal::StoreMode /*mode*/) { - for( int i = 0; i < n; i++ ) - ptr[i] = a.s[i]; + CV_Assert(isAligned)>(ptr)); + v_store(ptr, a); } /** @brief Combine vector from first elements of two vectors @@ -1940,6 +2030,17 @@ template inline v_reg v_cvt_f32(const v_reg& a) return c; } +template inline v_reg v_cvt_f32(const v_reg& a) +{ + v_reg c; + for( int i = 0; i < n; i++ ) + { + c.s[i] = (float)a.s[i]; + c.s[i+n] = 0; + } + return c; +} + template inline v_reg v_cvt_f32(const v_reg& a, const v_reg& b) { v_reg c; @@ -1954,36 +2055,76 @@ template inline v_reg v_cvt_f32(const v_reg& a, co /** @brief Convert to double Supported input type is cv::v_int32x4. */ -template inline v_reg v_cvt_f64(const v_reg& a) +CV_INLINE v_reg v_cvt_f64(const v_reg& a) { + enum { n = 2 }; v_reg c; for( int i = 0; i < n; i++ ) c.s[i] = (double)a.s[i]; return c; } +/** @brief Convert to double high part of vector + +Supported input type is cv::v_int32x4. */ +CV_INLINE v_reg v_cvt_f64_high(const v_reg& a) +{ + enum { n = 2 }; + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = (double)a.s[i + 2]; + return c; +} + /** @brief Convert to double Supported input type is cv::v_float32x4. */ -template inline v_reg v_cvt_f64(const v_reg& a) +CV_INLINE v_reg v_cvt_f64(const v_reg& a) { + enum { n = 2 }; v_reg c; for( int i = 0; i < n; i++ ) c.s[i] = (double)a.s[i]; return c; } +/** @brief Convert to double high part of vector + +Supported input type is cv::v_float32x4. */ +CV_INLINE v_reg v_cvt_f64_high(const v_reg& a) +{ + enum { n = 2 }; + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = (double)a.s[i + 2]; + return c; +} + /** @brief Convert to double Supported input type is cv::v_int64x2. */ -template inline v_reg v_cvt_f64(const v_reg& a) +CV_INLINE v_reg v_cvt_f64(const v_reg& a) { + enum { n = 2 }; v_reg c; for( int i = 0; i < n; i++ ) c.s[i] = (double)a.s[i]; return c; } +/** @brief Convert to double high part of vector + +Supported input type is cv::v_int64x2. */ +CV_INLINE v_reg v_cvt_f64_high(const v_reg& a) +{ + enum { n = 2 }; + v_reg c; + for( int i = 0; i < n; i++ ) + c.s[i] = (double)a.s[i]; + return c; +} + + template inline v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> v_lut(const _Tp* tab, const int* idx) { v_reg<_Tp, V_TypeTraits<_Tp>::nlanes128> c; @@ -2038,6 +2179,28 @@ template inline v_reg v_lut(const double* tab, const v_reg inline void v_lut_deinterleave(const float* tab, const v_reg& idx, v_reg& x, v_reg& y) { @@ -2062,7 +2225,7 @@ template inline void v_lut_deinterleave(const double* tab, const v_reg inline v_reg<_Tp, n> v_interleave_pairs(const v_reg<_Tp, n>& vec) { - v_reg c; + v_reg<_Tp, n> c; for (int i = 0; i < n/4; i++) { c.s[4*i ] = vec.s[4*i ]; @@ -2075,7 +2238,7 @@ template inline v_reg<_Tp, n> v_interleave_pairs(const v_re template inline v_reg<_Tp, n> v_interleave_quads(const v_reg<_Tp, n>& vec) { - v_reg c; + v_reg<_Tp, n> c; for (int i = 0; i < n/8; i++) { c.s[8*i ] = vec.s[8*i ]; @@ -2092,7 +2255,7 @@ template inline v_reg<_Tp, n> v_interleave_quads(const v_re template inline v_reg<_Tp, n> v_pack_triplets(const v_reg<_Tp, n>& vec) { - v_reg c; + v_reg<_Tp, n> c; for (int i = 0; i < n/4; i++) { c.s[3*i ] = vec.s[4*i ]; @@ -2523,6 +2686,17 @@ inline v_float32x4 v_matmuladd(const v_float32x4& v, const v_float32x4& m0, v.s[0]*m0.s[3] + v.s[1]*m1.s[3] + v.s[2]*m2.s[3] + m3.s[3]); } + +inline v_float64x2 v_dotprod_expand(const v_int32x4& a, const v_int32x4& b) +{ return v_fma(v_cvt_f64(a), v_cvt_f64(b), v_cvt_f64_high(a) * v_cvt_f64_high(b)); } +inline v_float64x2 v_dotprod_expand(const v_int32x4& a, const v_int32x4& b, const v_float64x2& c) +{ return v_fma(v_cvt_f64(a), v_cvt_f64(b), v_fma(v_cvt_f64_high(a), v_cvt_f64_high(b), c)); } + +inline v_float64x2 v_dotprod_expand_fast(const v_int32x4& a, const v_int32x4& b) +{ return v_dotprod_expand(a, b); } +inline v_float64x2 v_dotprod_expand_fast(const v_int32x4& a, const v_int32x4& b, const v_float64x2& c) +{ return v_dotprod_expand(a, b, c); } + ////// FP16 support /////// inline v_reg::nlanes128> @@ -2537,7 +2711,7 @@ v_load_expand(const float16_t* ptr) } inline void -v_pack_store(float16_t* ptr, v_reg::nlanes128>& v) +v_pack_store(float16_t* ptr, const v_reg::nlanes128>& v) { for( int i = 0; i < v.nlanes; i++ ) { diff --git a/modules/core/src/arithm.cpp b/modules/core/src/arithm.cpp index d6418bc9b5..2672ea194c 100644 --- a/modules/core/src/arithm.cpp +++ b/modules/core/src/arithm.cpp @@ -1492,7 +1492,8 @@ struct InRange_SIMD v_float32 low2 = vx_load(src2 + x + v_float32::nlanes); v_float32 high2 = vx_load(src3 + x + v_float32::nlanes); - v_pack_store(dst + x, v_pack(v_reinterpret_as_u32((values1 >= low1) & (high1 >= values1)), v_reinterpret_as_u32((values2 >= low2) & (high2 >= values2)))); + v_pack_store(dst + x, v_pack(v_reinterpret_as_u32(values1 >= low1) & v_reinterpret_as_u32(high1 >= values1), + v_reinterpret_as_u32(values2 >= low2) & v_reinterpret_as_u32(high2 >= values2))); } vx_cleanup(); return x; diff --git a/modules/core/src/arithm.simd.hpp b/modules/core/src/arithm.simd.hpp index e8bb61f24a..0cddc90998 100644 --- a/modules/core/src/arithm.simd.hpp +++ b/modules/core/src/arithm.simd.hpp @@ -1576,7 +1576,7 @@ struct op_div_scale } static inline Tvec pre(const Tvec& denom, const Tvec& res) { - const Tvec v_zero = Tvec(); + const Tvec v_zero = vx_setall(0); return v_select(denom == v_zero, v_zero, res); } static inline T1 r(T1 a, T1 denom, const T2* scalar) @@ -1826,7 +1826,7 @@ struct op_recip } static inline Tvec pre(const Tvec& denom, const Tvec& res) { - const Tvec v_zero = Tvec(); + const Tvec v_zero = vx_setall(0); return v_select(denom == v_zero, v_zero, res); } static inline T1 r(T1 denom, const T2* scalar) diff --git a/modules/core/src/lapack.cpp b/modules/core/src/lapack.cpp index 649f6baac5..486b7a5aba 100644 --- a/modules/core/src/lapack.cpp +++ b/modules/core/src/lapack.cpp @@ -916,8 +916,9 @@ double cv::invert( InputArray _src, OutputArray _dst, int method ) result = true; d = 1./d; #if CV_SIMD128 - static const float CV_DECL_ALIGNED(16) inv[4] = { 0.f,-0.f,-0.f,0.f }; - v_float32x4 s0 = (v_load_halves((const float*)srcdata, (const float*)(srcdata + srcstep)) * v_setall_f32((float)d)) ^ v_load((const float *)inv);//0123//3120 + const float d_32f = (float)d; + const v_float32x4 d_vec(d_32f, -d_32f, -d_32f, d_32f); + v_float32x4 s0 = v_load_halves((const float*)srcdata, (const float*)(srcdata + srcstep)) * d_vec;//0123//3120 s0 = v_extract<3>(s0, v_combine_low(v_rotate_right<1>(s0), s0)); v_store_low((float*)dstdata, s0); v_store_high((float*)(dstdata + dststep), s0); @@ -946,7 +947,7 @@ double cv::invert( InputArray _src, OutputArray _dst, int method ) v_float64x2 s0 = v_load((const double*)srcdata) * det; v_float64x2 s1 = v_load((const double*)(srcdata+srcstep)) * det; v_float64x2 sm = v_extract<1>(s1, s0);//30 - v_float64x2 ss = v_extract<1>(s0, s1) ^ v_setall_f64(-0.);//12 + v_float64x2 ss = v_setall(0) - v_extract<1>(s0, s1);//12 v_store((double*)dstdata, v_combine_low(sm, ss));//31 v_store((double*)(dstdata + dststep), v_combine_high(ss, sm));//20 #else diff --git a/modules/core/src/mathfuncs_core.simd.hpp b/modules/core/src/mathfuncs_core.simd.hpp index ba8a5477de..1bf36bb174 100644 --- a/modules/core/src/mathfuncs_core.simd.hpp +++ b/modules/core/src/mathfuncs_core.simd.hpp @@ -725,7 +725,7 @@ void log32f( const float *_x, float *y, int n ) yf0 = v_fma(v_cvt_f32(yi0), vln2, yf0); - v_float32 delta = v_reinterpret_as_f32(h0 == vx_setall_s32(510)) & vshift; + v_float32 delta = v_select(v_reinterpret_as_f32(h0 == vx_setall_s32(510)), vshift, vx_setall(0)); xf0 = v_fma((v_reinterpret_as_f32(xi0) - v1), xf0, delta); v_float32 zf0 = v_fma(xf0, vA0, vA1); diff --git a/modules/core/src/ovx.cpp b/modules/core/src/ovx.cpp index 9685cbaed2..560c601fce 100644 --- a/modules/core/src/ovx.cpp +++ b/modules/core/src/ovx.cpp @@ -8,6 +8,7 @@ // OpenVX related functions #include "precomp.hpp" +#include "opencv2/core/utils/tls.hpp" #include "opencv2/core/ovx.hpp" #include "opencv2/core/openvx/ovx_defs.hpp" diff --git a/modules/core/test/test_intrin_emulator.cpp b/modules/core/test/test_intrin_emulator.cpp index 0ae3c02b86..347bc8fee1 100644 --- a/modules/core/test/test_intrin_emulator.cpp +++ b/modules/core/test/test_intrin_emulator.cpp @@ -3,22 +3,14 @@ // of this distribution and at http://opencv.org/license.html. #include "test_precomp.hpp" -// see "opencv2/core/hal/intrin.hpp" -#define CV_CPU_OPTIMIZATION_HAL_NAMESPACE hal_EMULATOR_CPP -#define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN namespace hal_EMULATOR_CPP { -#define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END } - // see "opencv2/core/private/cv_cpu_include_simd_declarations.hpp" //#define CV_CPU_OPTIMIZATION_DECLARATIONS_ONLY -#define CV_FORCE_SIMD128_CPP +#undef CV_FORCE_SIMD128_CPP +#define CV_FORCE_SIMD128_CPP 1 #undef CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN #undef CV_CPU_OPTIMIZATION_NAMESPACE_END #define CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN namespace opt_EMULATOR_CPP { #define CV_CPU_OPTIMIZATION_NAMESPACE_END } #include "test_intrin128.simd.hpp" -#undef CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN -#undef CV_CPU_OPTIMIZATION_NAMESPACE_END -#undef CV_CPU_DISPATCH_MODE -#undef CV_FORCE_SIMD128_CPP // tests implementation is in test_intrin_utils.hpp diff --git a/modules/core/test/test_intrin_utils.hpp b/modules/core/test/test_intrin_utils.hpp index 4d2bd46737..d8d94fdb0d 100644 --- a/modules/core/test/test_intrin_utils.hpp +++ b/modules/core/test/test_intrin_utils.hpp @@ -222,7 +222,10 @@ template std::ostream & operator<<(std::ostream & out, const Data static inline void EXPECT_COMPARE_EQ_(const T a, const T b); +template static inline void EXPECT_COMPARE_EQ_(const T a, const T b) +{ + EXPECT_EQ(a, b); +} template<> inline void EXPECT_COMPARE_EQ_(const float a, const float b) { EXPECT_FLOAT_EQ( a, b ); @@ -742,12 +745,12 @@ template struct TheTest for (int i = 0; i < n; ++i) { SCOPED_TRACE(cv::format("i=%d", i)); - EXPECT_EQ((double)dataA[i*2] * (double)dataA[i*2] + - (double)dataA[i*2 + 1] * (double)dataA[i*2 + 1], resA[i]); - EXPECT_EQ((double)dataB[i*2] * (double)dataB[i*2] + - (double)dataB[i*2 + 1] * (double)dataB[i*2 + 1], resB[i]); - EXPECT_EQ((double)dataA[i*2] * (double)dataB[i*2] + - (double)dataA[i*2 + 1] * (double)dataB[i*2 + 1] + dataC[i], resC[i]); + EXPECT_COMPARE_EQ((double)dataA[i*2] * (double)dataA[i*2] + + (double)dataA[i*2 + 1] * (double)dataA[i*2 + 1], resA[i]); + EXPECT_COMPARE_EQ((double)dataB[i*2] * (double)dataB[i*2] + + (double)dataB[i*2 + 1] * (double)dataB[i*2 + 1], resB[i]); + EXPECT_COMPARE_EQ((double)dataA[i*2] * (double)dataB[i*2] + + (double)dataA[i*2 + 1] * (double)dataB[i*2 + 1] + dataC[i], resC[i]); } #endif return *this; diff --git a/modules/dnn/src/tensorflow/tf_graph_simplifier.cpp b/modules/dnn/src/tensorflow/tf_graph_simplifier.cpp index 926d1c5809..d6e52f7dbe 100644 --- a/modules/dnn/src/tensorflow/tf_graph_simplifier.cpp +++ b/modules/dnn/src/tensorflow/tf_graph_simplifier.cpp @@ -950,6 +950,7 @@ void sortByExecutionOrder(tensorflow::GraphDef& net) for (int i = 0; i < net.node_size(); ++i) { const tensorflow::NodeDef& node = net.node(i); + int numInputsInGraph = 0; for (int j = 0; j < node.input_size(); ++j) { std::string inpName = node.input(j); @@ -957,22 +958,25 @@ void sortByExecutionOrder(tensorflow::GraphDef& net) inpName = inpName.substr(inpName.find('^') + 1); nodesMapIt = nodesMap.find(inpName); - CV_Assert(nodesMapIt != nodesMap.end()); - edges[nodesMapIt->second].push_back(i); + if (nodesMapIt != nodesMap.end()) + { + edges[nodesMapIt->second].push_back(i); + numInputsInGraph += 1; + } } - if (node.input_size() == 0) + if (numInputsInGraph == 0) nodesToAdd.push_back(i); else { if (node.op() == "Merge" || node.op() == "RefMerge") { int numControlEdges = 0; - for (int j = 0; j < node.input_size(); ++j) + for (int j = 0; j < numInputsInGraph; ++j) numControlEdges += node.input(j)[0] == '^'; numRefsToAdd[i] = numControlEdges + 1; } else - numRefsToAdd[i] = node.input_size(); + numRefsToAdd[i] = numInputsInGraph; } } diff --git a/modules/dnn/src/tensorflow/tf_importer.cpp b/modules/dnn/src/tensorflow/tf_importer.cpp index b9a8920bd6..80a62ccfe3 100644 --- a/modules/dnn/src/tensorflow/tf_importer.cpp +++ b/modules/dnn/src/tensorflow/tf_importer.cpp @@ -715,6 +715,10 @@ void TFImporter::populateNet(Net dstNet) simplifySubgraphs(netBin); sortByExecutionOrder(netBin); } + else + { + sortByExecutionOrder(netTxt); + } std::set layers_to_ignore; diff --git a/modules/features2d/src/fast_score.cpp b/modules/features2d/src/fast_score.cpp index 73126e647b..0bc011af49 100644 --- a/modules/features2d/src/fast_score.cpp +++ b/modules/features2d/src/fast_score.cpp @@ -303,7 +303,8 @@ int cornerScore<8>(const uchar* ptr, const int pixel[], int threshold) for (k = 0; k < N; k++) d[k] = (short)(v - ptr[pixel[k]]); -#if CV_SIMD128 +#if CV_SIMD128 \ + && (!defined(CV_SIMD128_CPP) || (!defined(__GNUC__) || __GNUC__ != 5)) // "movdqa" bug on "v_load(d + 1)" line (Ubuntu 16.04 + GCC 5.4) if (true) { v_int16x8 v0 = v_load(d + 1); diff --git a/modules/imgcodecs/src/utils.cpp b/modules/imgcodecs/src/utils.cpp index 8ce1b14af1..0962ebea62 100644 --- a/modules/imgcodecs/src/utils.cpp +++ b/modules/imgcodecs/src/utils.cpp @@ -56,65 +56,65 @@ int validateToInt(size_t sz) #define cG (int)(0.587*(1 << SCALE) + 0.5) #define cB ((1 << SCALE) - cR - cG) -void icvCvt_BGR2Gray_8u_C3C1R( const uchar* rgb, int rgb_step, +void icvCvt_BGR2Gray_8u_C3C1R( const uchar* bgr, int bgr_step, uchar* gray, int gray_step, Size size, int _swap_rb ) { int i; for( ; size.height--; gray += gray_step ) { - short cRGB0 = cR; - short cRGB2 = cB; - if (_swap_rb) std::swap(cRGB0, cRGB2); - for( i = 0; i < size.width; i++, rgb += 3 ) + short cBGR0 = cB; + short cBGR2 = cR; + if (_swap_rb) std::swap(cBGR0, cBGR2); + for( i = 0; i < size.width; i++, bgr += 3 ) { - int t = descale( rgb[0]*cRGB0 + rgb[1]*cG + rgb[2]*cRGB2, SCALE ); + int t = descale( bgr[0]*cBGR0 + bgr[1]*cG + bgr[2]*cBGR2, SCALE ); gray[i] = (uchar)t; } - rgb += rgb_step - size.width*3; + bgr += bgr_step - size.width*3; } } -void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* rgb, int rgb_step, +void icvCvt_BGRA2Gray_16u_CnC1R( const ushort* bgr, int bgr_step, ushort* gray, int gray_step, Size size, int ncn, int _swap_rb ) { int i; for( ; size.height--; gray += gray_step ) { - short cRGB0 = cR; - short cRGB2 = cB; - if (_swap_rb) std::swap(cRGB0, cRGB2); - for( i = 0; i < size.width; i++, rgb += ncn ) + short cBGR0 = cB; + short cBGR2 = cR; + if (_swap_rb) std::swap(cBGR0, cBGR2); + for( i = 0; i < size.width; i++, bgr += ncn ) { - int t = descale( rgb[0]*cRGB0 + rgb[1]*cG + rgb[2]*cRGB2, SCALE ); + int t = descale( bgr[0]*cBGR0 + bgr[1]*cG + bgr[2]*cBGR2, SCALE ); gray[i] = (ushort)t; } - rgb += rgb_step - size.width*ncn; + bgr += bgr_step - size.width*ncn; } } -void icvCvt_BGRA2Gray_8u_C4C1R( const uchar* rgba, int rgba_step, +void icvCvt_BGRA2Gray_8u_C4C1R( const uchar* bgra, int rgba_step, uchar* gray, int gray_step, Size size, int _swap_rb ) { int i; for( ; size.height--; gray += gray_step ) { - short cRGB0 = cR; - short cRGB2 = cB; - if (_swap_rb) std::swap(cRGB0, cRGB2); - for( i = 0; i < size.width; i++, rgba += 4 ) + short cBGR0 = cB; + short cBGR2 = cR; + if (_swap_rb) std::swap(cBGR0, cBGR2); + for( i = 0; i < size.width; i++, bgra += 4 ) { - int t = descale( rgba[0]*cRGB0 + rgba[1]*cG + rgba[2]*cRGB2, SCALE ); + int t = descale( bgra[0]*cBGR0 + bgra[1]*cG + bgra[2]*cBGR2, SCALE ); gray[i] = (uchar)t; } - rgba += rgba_step - size.width*4; + bgra += rgba_step - size.width*4; } } diff --git a/modules/imgproc/src/corner.avx.cpp b/modules/imgproc/src/corner.avx.cpp index 1a62db3074..8d8083eee5 100644 --- a/modules/imgproc/src/corner.avx.cpp +++ b/modules/imgproc/src/corner.avx.cpp @@ -42,6 +42,7 @@ //M*/ #include "precomp.hpp" +#undef CV_FORCE_SIMD128_CPP // expected AVX implementation only #include "opencv2/core/hal/intrin.hpp" #include "corner.hpp" diff --git a/modules/imgproc/src/resize.cpp b/modules/imgproc/src/resize.cpp index 02f78819de..861a1f2eac 100644 --- a/modules/imgproc/src/resize.cpp +++ b/modules/imgproc/src/resize.cpp @@ -1109,23 +1109,29 @@ resizeNN( const Mat& src, Mat& dst, double fx, double fy ) struct VResizeNoVec { - int operator()(const uchar**, uchar*, const uchar*, int ) const { return 0; } + template + int operator()(const WT**, T*, const BT*, int ) const + { + return 0; + } }; struct HResizeNoVec { - int operator()(const uchar**, uchar**, int, const int*, - const uchar*, int, int, int, int, int) const { return 0; } + template inline + int operator()(const T**, WT**, int, const int*, + const AT*, int, int, int, int, int) const + { + return 0; + } }; #if CV_SIMD struct VResizeLinearVec_32s8u { - int operator()(const uchar** _src, uchar* dst, const uchar* _beta, int width ) const + int operator()(const int** src, uchar* dst, const short* beta, int width) const { - const int** src = (const int**)_src; - const short* beta = (const short*)_beta; const int *S0 = src[0], *S1 = src[1]; int x = 0; v_int16 b0 = vx_setall_s16(beta[0]), b1 = vx_setall_s16(beta[1]); @@ -1153,12 +1159,9 @@ struct VResizeLinearVec_32s8u struct VResizeLinearVec_32f16u { - int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + int operator()(const float** src, ushort* dst, const float* beta, int width) const { - const float** src = (const float**)_src; - const float* beta = (const float*)_beta; const float *S0 = src[0], *S1 = src[1]; - ushort* dst = (ushort*)_dst; int x = 0; v_float32 b0 = vx_setall_f32(beta[0]), b1 = vx_setall_f32(beta[1]); @@ -1183,12 +1186,9 @@ struct VResizeLinearVec_32f16u struct VResizeLinearVec_32f16s { - int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + int operator()(const float** src, short* dst, const float* beta, int width) const { - const float** src = (const float**)_src; - const float* beta = (const float*)_beta; const float *S0 = src[0], *S1 = src[1]; - short* dst = (short*)_dst; int x = 0; v_float32 b0 = vx_setall_f32(beta[0]), b1 = vx_setall_f32(beta[1]); @@ -1213,12 +1213,9 @@ struct VResizeLinearVec_32f16s struct VResizeLinearVec_32f { - int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + int operator()(const float** src, float* dst, const float* beta, int width) const { - const float** src = (const float**)_src; - const float* beta = (const float*)_beta; const float *S0 = src[0], *S1 = src[1]; - float* dst = (float*)_dst; int x = 0; v_float32 b0 = vx_setall_f32(beta[0]), b1 = vx_setall_f32(beta[1]); @@ -1237,10 +1234,8 @@ struct VResizeLinearVec_32f struct VResizeCubicVec_32s8u { - int operator()(const uchar** _src, uchar* dst, const uchar* _beta, int width ) const + int operator()(const int** src, uchar* dst, const short* beta, int width) const { - const int** src = (const int**)_src; - const short* beta = (const short*)_beta; const int *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3]; int x = 0; float scale = 1.f/(INTER_RESIZE_COEF_SCALE*INTER_RESIZE_COEF_SCALE); @@ -1274,12 +1269,9 @@ struct VResizeCubicVec_32s8u struct VResizeCubicVec_32f16u { - int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + int operator()(const float** src, ushort* dst, const float* beta, int width) const { - const float** src = (const float**)_src; - const float* beta = (const float*)_beta; const float *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3]; - ushort* dst = (ushort*)_dst; int x = 0; v_float32 b0 = vx_setall_f32(beta[0]), b1 = vx_setall_f32(beta[1]), b2 = vx_setall_f32(beta[2]), b3 = vx_setall_f32(beta[3]); @@ -1300,12 +1292,9 @@ struct VResizeCubicVec_32f16u struct VResizeCubicVec_32f16s { - int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + int operator()(const float** src, short* dst, const float* beta, int width) const { - const float** src = (const float**)_src; - const float* beta = (const float*)_beta; const float *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3]; - short* dst = (short*)_dst; int x = 0; v_float32 b0 = vx_setall_f32(beta[0]), b1 = vx_setall_f32(beta[1]), b2 = vx_setall_f32(beta[2]), b3 = vx_setall_f32(beta[3]); @@ -1326,12 +1315,9 @@ struct VResizeCubicVec_32f16s struct VResizeCubicVec_32f { - int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + int operator()(const float** src, float* dst, const float* beta, int width) const { - const float** src = (const float**)_src; - const float* beta = (const float*)_beta; const float *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3]; - float* dst = (float*)_dst; int x = 0; v_float32 b0 = vx_setall_f32(beta[0]), b1 = vx_setall_f32(beta[1]), b2 = vx_setall_f32(beta[2]), b3 = vx_setall_f32(beta[3]); @@ -1351,10 +1337,12 @@ struct VResizeCubicVec_32f struct VResizeLanczos4Vec_32f16u { - int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + int operator()(const float** src, ushort* dst, const float* beta, int width) const { - if (CV_CPU_HAS_SUPPORT_SSE4_1) return opt_SSE4_1::VResizeLanczos4Vec_32f16u_SSE41(_src, _dst, _beta, width); - else return 0; + if (CV_CPU_HAS_SUPPORT_SSE4_1) + return opt_SSE4_1::VResizeLanczos4Vec_32f16u_SSE41(src, dst, beta, width); + else + return 0; } }; @@ -1362,13 +1350,10 @@ struct VResizeLanczos4Vec_32f16u struct VResizeLanczos4Vec_32f16u { - int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + int operator()(const float** src, ushort* dst, const float* beta, int width ) const { - const float** src = (const float**)_src; - const float* beta = (const float*)_beta; const float *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3], *S4 = src[4], *S5 = src[5], *S6 = src[6], *S7 = src[7]; - ushort * dst = (ushort*)_dst; int x = 0; v_float32 b0 = vx_setall_f32(beta[0]), b1 = vx_setall_f32(beta[1]), b2 = vx_setall_f32(beta[2]), b3 = vx_setall_f32(beta[3]), @@ -1401,13 +1386,10 @@ struct VResizeLanczos4Vec_32f16u struct VResizeLanczos4Vec_32f16s { - int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + int operator()(const float** src, short* dst, const float* beta, int width ) const { - const float** src = (const float**)_src; - const float* beta = (const float*)_beta; const float *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3], *S4 = src[4], *S5 = src[5], *S6 = src[6], *S7 = src[7]; - short * dst = (short*)_dst; int x = 0; v_float32 b0 = vx_setall_f32(beta[0]), b1 = vx_setall_f32(beta[1]), b2 = vx_setall_f32(beta[2]), b3 = vx_setall_f32(beta[3]), @@ -1438,13 +1420,10 @@ struct VResizeLanczos4Vec_32f16s struct VResizeLanczos4Vec_32f { - int operator()(const uchar** _src, uchar* _dst, const uchar* _beta, int width ) const + int operator()(const float** src, float* dst, const float* beta, int width ) const { - const float** src = (const float**)_src; - const float* beta = (const float*)_beta; const float *S0 = src[0], *S1 = src[1], *S2 = src[2], *S3 = src[3], *S4 = src[4], *S5 = src[5], *S6 = src[6], *S7 = src[7]; - float* dst = (float*)_dst; int x = 0; v_float32 b0 = vx_setall_f32(beta[0]), b1 = vx_setall_f32(beta[1]), @@ -1489,12 +1468,9 @@ typedef VResizeNoVec VResizeLanczos4Vec_32f; template struct HResizeLinearVec_X4 { - int operator()(const uchar** _src, uchar** _dst, int count, const int* xofs, - const uchar* _alpha, int, int, int cn, int, int xmax) const + int operator()(const ST** src, DT** dst, int count, const int* xofs, + const AT* alpha, int, int, int cn, int, int xmax) const { - const ST **src = (const ST**)_src; - const AT *alpha = (const AT*)_alpha; - DT **dst = (DT**)_dst; const int nlanes = 4; const int len0 = xmax & -nlanes; int dx = 0, k = 0; @@ -1549,11 +1525,9 @@ struct HResizeLinearVec_X4 struct HResizeLinearVecU8_X4 { - int operator()(const uchar** src, uchar** _dst, int count, const int* xofs, - const uchar* _alpha, int smax, int, int cn, int, int xmax) const + int operator()(const uchar** src, int** dst, int count, const int* xofs, + const short* alpha/*[xmax]*/, int smax, int /*dmax*/, int cn, int /*xmin*/, int xmax) const { - const short *alpha = (const short*)_alpha; - int **dst = (int**)_dst; int dx = 0, k = 0; if(cn == 1) @@ -1827,8 +1801,8 @@ struct HResizeLinear int dx, k; VecOp vecOp; - int dx0 = vecOp((const uchar**)src, (uchar**)dst, count, - xofs, (const uchar*)alpha, swidth, dwidth, cn, xmin, xmax ); + int dx0 = vecOp(src, dst, count, + xofs, alpha, swidth, dwidth, cn, xmin, xmax ); for( k = 0; k <= count - 2; k+=2 ) { @@ -1881,7 +1855,7 @@ struct VResizeLinear CastOp castOp; VecOp vecOp; - int x = vecOp((const uchar**)src, (uchar*)dst, (const uchar*)beta, width); + int x = vecOp(src, dst, beta, width); #if CV_ENABLE_UNROLLED for( ; x <= width - 4; x += 4 ) { @@ -1912,7 +1886,7 @@ struct VResizeLinear::eye(3, 3), T = Mat_::zeros(3, 1); + //! [iomati] + //! [customIOi] MyData m(1); + //! [customIOi] + //! [open] FileStorage fs(filename, FileStorage::WRITE); + // or: + // FileStorage fs; + // fs.open(filename, FileStorage::WRITE); + //! [open] + //! [writeNum] fs << "iterationNr" << 100; + //! [writeNum] + //! [writeStr] fs << "strings" << "["; // text - string sequence fs << "image1.jpg" << "Awesomeness" << "../data/baboon.jpg"; fs << "]"; // close sequence + //! [writeStr] + //! [writeMap] fs << "Mapping"; // text - mapping fs << "{" << "One" << 1; fs << "Two" << 2 << "}"; + //! [writeMap] + //! [iomatw] fs << "R" << R; // cv::Mat fs << "T" << T; + //! [iomatw] + //! [customIOw] fs << "MyData" << m; // your own data structures + //! [customIOw] + //! [close] fs.release(); // explicit close + //! [close] cout << "Write Done." << endl; } @@ -101,9 +126,11 @@ int main(int ac, char** av) FileStorage fs; fs.open(filename, FileStorage::READ); + //! [readNum] int itNr; //fs["iterationNr"] >> itNr; itNr = (int) fs["iterationNr"]; + //! [readNum] cout << itNr; if (!fs.isOpened()) { @@ -112,6 +139,7 @@ int main(int ac, char** av) return 1; } + //! [readStr] FileNode n = fs["strings"]; // Read string sequence - Get node if (n.type() != FileNode::SEQ) { @@ -122,19 +150,26 @@ int main(int ac, char** av) FileNodeIterator it = n.begin(), it_end = n.end(); // Go through the node for (; it != it_end; ++it) cout << (string)*it << endl; + //! [readStr] + //! [readMap] n = fs["Mapping"]; // Read mappings from a sequence cout << "Two " << (int)(n["Two"]) << "; "; cout << "One " << (int)(n["One"]) << endl << endl; + //! [readMap] MyData m; Mat R, T; + //! [iomat] fs["R"] >> R; // Read cv::Mat fs["T"] >> T; + //! [iomat] + //! [customIO] fs["MyData"] >> m; // Read your own structure_ + //! [customIO] cout << endl << "R = " << R << endl; @@ -142,9 +177,11 @@ int main(int ac, char** av) cout << "MyData = " << endl << m << endl << endl; //Show default behavior for non existing nodes + //! [nonexist] cout << "Attempt to read NonExisting (should initialize the data structure with its default)."; fs["NonExisting"] >> m; cout << endl << "NonExisting = " << endl << m << endl; + //! [nonexist] } cout << endl diff --git a/samples/java/tutorial_code/video/meanshift/CamshiftDemo.java b/samples/java/tutorial_code/video/meanshift/CamshiftDemo.java new file mode 100644 index 0000000000..6717446a7f --- /dev/null +++ b/samples/java/tutorial_code/video/meanshift/CamshiftDemo.java @@ -0,0 +1,75 @@ +import java.util.Arrays; +import org.opencv.core.*; +import org.opencv.highgui.HighGui; +import org.opencv.imgproc.Imgproc; +import org.opencv.video.Video; +import org.opencv.videoio.VideoCapture; + + +class Camshift { + public void run(String[] args) { + String filename = args[0]; + VideoCapture capture = new VideoCapture(filename); + if (!capture.isOpened()) { + System.out.println("Unable to open file!"); + System.exit(-1); + } + + Mat frame = new Mat(), hsv_roi = new Mat(), mask = new Mat(), roi; + + // take the first frame of the video + capture.read(frame); + + //setup initial location of window + Rect track_window = new Rect(300, 200, 100, 50); + + // set up the ROI for tracking + roi = new Mat(frame, track_window); + Imgproc.cvtColor(roi, hsv_roi, Imgproc.COLOR_BGR2HSV); + Core.inRange(hsv_roi, new Scalar(0, 60, 32), new Scalar(180, 255, 255), mask); + + MatOfFloat range = new MatOfFloat(0, 256); + Mat roi_hist = new Mat(); + MatOfInt histSize = new MatOfInt(180); + MatOfInt channels = new MatOfInt(0); + Imgproc.calcHist(Arrays.asList(hsv_roi), channels, mask, roi_hist, histSize, range); + Core.normalize(roi_hist, roi_hist, 0, 255, Core.NORM_MINMAX); + + // Setup the termination criteria, either 10 iteration or move by atleast 1 pt + TermCriteria term_crit = new TermCriteria(TermCriteria.EPS | TermCriteria.COUNT, 10, 1); + + while (true) { + Mat hsv = new Mat() , dst = new Mat(); + capture.read(frame); + if (frame.empty()) { + break; + } + Imgproc.cvtColor(frame, hsv, Imgproc.COLOR_BGR2HSV); + Imgproc.calcBackProject(Arrays.asList(hsv), channels, roi_hist, dst, range, 1); + + // apply camshift to get the new location + RotatedRect rot_rect = Video.CamShift(dst, track_window, term_crit); + + // Draw it on image + Point[] points = new Point[4]; + rot_rect.points(points); + for (int i = 0; i < 4 ;i++) { + Imgproc.line(frame, points[i], points[(i+1)%4], new Scalar(255, 0, 0),2); + } + + HighGui.imshow("img2", frame); + int keyboard = HighGui.waitKey(30); + if (keyboard == 'q'|| keyboard == 27) { + break; + } + } + System.exit(0); + } +} + +public class CamshiftDemo { + public static void main(String[] args) { + System.loadLibrary(Core.NATIVE_LIBRARY_NAME); + new Camshift().run(args); + } +} diff --git a/samples/java/tutorial_code/video/meanshift/MeanshiftDemo.java b/samples/java/tutorial_code/video/meanshift/MeanshiftDemo.java new file mode 100644 index 0000000000..5fbdd0efff --- /dev/null +++ b/samples/java/tutorial_code/video/meanshift/MeanshiftDemo.java @@ -0,0 +1,70 @@ +import java.util.Arrays; +import org.opencv.core.*; +import org.opencv.highgui.HighGui; +import org.opencv.imgproc.Imgproc; +import org.opencv.video.Video; +import org.opencv.videoio.VideoCapture; + + +class Meanshift { + public void run(String[] args) { + String filename = args[0]; + VideoCapture capture = new VideoCapture(filename); + if (!capture.isOpened()) { + System.out.println("Unable to open file!"); + System.exit(-1); + } + Mat frame = new Mat(), hsv_roi = new Mat(), mask = new Mat(), roi; + + // take the first frame of the video + capture.read(frame); + + //setup initial location of window + Rect track_window = new Rect(300, 200, 100, 50); + + // setup initial location of window + roi = new Mat(frame, track_window); + Imgproc.cvtColor(roi, hsv_roi, Imgproc.COLOR_BGR2HSV); + Core.inRange(hsv_roi, new Scalar(0, 60, 32), new Scalar(180, 255, 255), mask); + + MatOfFloat range = new MatOfFloat(0, 256); + Mat roi_hist = new Mat(); + MatOfInt histSize = new MatOfInt(180); + MatOfInt channels = new MatOfInt(0); + Imgproc.calcHist(Arrays.asList(hsv_roi), channels, mask, roi_hist, histSize, range); + Core.normalize(roi_hist, roi_hist, 0, 255, Core.NORM_MINMAX); + + // Setup the termination criteria, either 10 iteration or move by atleast 1 pt + TermCriteria term_crit = new TermCriteria(TermCriteria.EPS | TermCriteria.COUNT, 10, 1); + + while (true) { + Mat hsv = new Mat() , dst = new Mat(); + capture.read(frame); + if (frame.empty()) { + break; + } + Imgproc.cvtColor(frame, hsv, Imgproc.COLOR_BGR2HSV); + Imgproc.calcBackProject(Arrays.asList(hsv), channels, roi_hist, dst, range, 1); + + // apply meanshift to get the new location + Video.meanShift(dst, track_window, term_crit); + + // Draw it on image + Imgproc.rectangle(frame, track_window, new Scalar(255, 0, 0), 2); + HighGui.imshow("img2", frame); + + int keyboard = HighGui.waitKey(30); + if (keyboard == 'q' || keyboard == 27) { + break; + } + } + System.exit(0); + } +} + +public class MeanshiftDemo { + public static void main(String[] args) { + System.loadLibrary(Core.NATIVE_LIBRARY_NAME); + new Meanshift().run(args); + } +} diff --git a/samples/java/tutorial_code/video/optical_flow/OpticalFlowDemo.java b/samples/java/tutorial_code/video/optical_flow/OpticalFlowDemo.java new file mode 100644 index 0000000000..cf9f678869 --- /dev/null +++ b/samples/java/tutorial_code/video/optical_flow/OpticalFlowDemo.java @@ -0,0 +1,96 @@ +import java.util.ArrayList; +import java.util.Random; +import org.opencv.core.*; +import org.opencv.highgui.HighGui; +import org.opencv.imgproc.Imgproc; +import org.opencv.video.Video; +import org.opencv.videoio.VideoCapture; + +class OptFlow { + public void run(String[] args) { + String filename = args[0]; + VideoCapture capture = new VideoCapture(filename); + if (!capture.isOpened()) { + System.out.println("Unable to open this file"); + System.exit(-1); + } + + + // Create some random colors + Scalar[] colors = new Scalar[100]; + Random rng = new Random(); + for (int i = 0 ; i < 100 ; i++) { + int r = rng.nextInt(256); + int g = rng.nextInt(256); + int b = rng.nextInt(256); + colors[i] = new Scalar(r, g, b); + } + + Mat old_frame = new Mat() , old_gray = new Mat(); + + // Since the function Imgproc.goodFeaturesToTrack requires MatofPoint + // therefore first p0MatofPoint is passed to the function and then converted to MatOfPoint2f + MatOfPoint p0MatofPoint = new MatOfPoint(); + capture.read(old_frame); + Imgproc.cvtColor(old_frame, old_gray, Imgproc.COLOR_BGR2GRAY); + Imgproc.goodFeaturesToTrack(old_gray, p0MatofPoint,100,0.3,7, new Mat(),7,false,0.04); + + MatOfPoint2f p0 = new MatOfPoint2f(p0MatofPoint.toArray()) , p1 = new MatOfPoint2f(); + + // Create a mask image for drawing purposes + Mat mask = Mat.zeros(old_frame.size(), old_frame.type()); + + while (true) { + Mat frame = new Mat(), frame_gray = new Mat(); + capture.read(frame); + if (frame.empty()) { + break; + } + + Imgproc.cvtColor(frame, frame_gray, Imgproc.COLOR_BGR2GRAY); + + // calculate optical flow + MatOfByte status = new MatOfByte(); + MatOfFloat err = new MatOfFloat(); + TermCriteria criteria = new TermCriteria(TermCriteria.COUNT + TermCriteria.EPS,10,0.03); + Video.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, p1, status, err, new Size(15,15),2, criteria); + + byte StatusArr[] = status.toArray(); + Point p0Arr[] = p0.toArray(); + Point p1Arr[] = p1.toArray(); + ArrayList good_new = new ArrayList<>(); + + for (int i = 0; i flow_parts = new ArrayList<>(2); + Core.split(flow, flow_parts); + Mat magnitude = new Mat(), angle = new Mat(), magn_norm = new Mat(); + Core.cartToPolar(flow_parts.get(0), flow_parts.get(1), magnitude, angle,true); + Core.normalize(magnitude, magn_norm,0.0,1.0, Core.NORM_MINMAX); + float factor = (float) ((1.0/360.0)*(180.0/255.0)); + Mat new_angle = new Mat(); + Core.multiply(angle, new Scalar(factor), new_angle); + + //build hsv image + ArrayList _hsv = new ArrayList<>() ; + Mat hsv = new Mat(), hsv8 = new Mat(), bgr = new Mat(); + + _hsv.add(new_angle); + _hsv.add(Mat.ones(angle.size(), CvType.CV_32F)); + _hsv.add(magn_norm); + Core.merge(_hsv, hsv); + hsv.convertTo(hsv8, CvType.CV_8U, 255.0); + Imgproc.cvtColor(hsv8, bgr, Imgproc.COLOR_HSV2BGR); + + HighGui.imshow("frame2", bgr); + + int keyboard = HighGui.waitKey(30); + if (keyboard == 'q' || keyboard == 27) { + break; + } + prvs = next; + } + System.exit(0); + } +} + +public class OpticalFlowDenseDemo { + public static void main(String[] args) { + System.loadLibrary(Core.NATIVE_LIBRARY_NAME); + new OptFlowDense().run(args); + } +} diff --git a/samples/python/tutorial_code/core/file_input_output/file_input_output.py b/samples/python/tutorial_code/core/file_input_output/file_input_output.py new file mode 100644 index 0000000000..e3adb216a5 --- /dev/null +++ b/samples/python/tutorial_code/core/file_input_output/file_input_output.py @@ -0,0 +1,156 @@ +from __future__ import print_function + +import numpy as np +import cv2 as cv +import sys + +def help(filename): + print ( + ''' + {0} shows the usage of the OpenCV serialization functionality. \n\n + usage:\n + python3 {0} outputfile.yml.gz\n\n + The output file may be either in XML, YAML or JSON. You can even compress it\n + by specifying this in its extension like xml.gz yaml.gz etc... With\n + FileStorage you can serialize objects in OpenCV.\n\n + For example: - create a class and have it serialized\n + - use it to read and write matrices.\n + '''.format(filename) + ) + +class MyData: + A = 97 + X = np.pi + name = 'mydata1234' + + def __repr__(self): + s = '{ name = ' + self.name + ', X = ' + str(self.X) + s = s + ', A = ' + str(self.A) + '}' + return s + + ## [inside] + def write(self, fs): + fs.write('MyData','{') + fs.write('A', self.A) + fs.write('X', self.X) + fs.write('name', self.name) + fs.write('MyData','}') + + def read(self, node): + if (not node.empty()): + self.A = int(node.getNode('A').real()) + self.X = node.getNode('X').real() + self.name = node.getNode('name').string() + else: + self.A = self.X = 0 + self.name = '' + ## [inside] + +def main(argv): + if len(argv) != 2: + help(argv[0]) + exit(1) + + # write + ## [iomati] + R = np.eye(3,3) + T = np.zeros((3,1)) + ## [iomati] + ## [customIOi] + m = MyData() + ## [customIOi] + + filename = argv[1] + + ## [open] + s = cv.FileStorage(filename, cv.FileStorage_WRITE) + # or: + # s = cv.FileStorage() + # s.open(filename, cv.FileStorage_WRITE) + ## [open] + + ## [writeNum] + s.write('iterationNr', 100) + ## [writeNum] + + ## [writeStr] + s.write('strings', '[') + s.write('image1.jpg','Awesomeness') + s.write('../data/baboon.jpg',']') + ## [writeStr] + + ## [writeMap] + s.write ('Mapping', '{') + s.write ('One', 1) + s.write ('Two', 2) + s.write ('Mapping', '}') + ## [writeMap] + + ## [iomatw] + s.write ('R_MAT', R) + s.write ('T_MAT', T) + ## [iomatw] + + ## [customIOw] + m.write(s) + ## [customIOw] + ## [close] + s.release() + ## [close] + print ('Write Done.') + + # read + print ('\nReading: ') + s = cv.FileStorage() + s.open(filename, cv.FileStorage_READ) + + ## [readNum] + n = s.getNode('iterationNr') + itNr = int(n.real()) + ## [readNum] + print (itNr) + + if (not s.isOpened()): + print ('Failed to open ', filename, file=sys.stderr) + help(argv[0]) + exit(1) + + ## [readStr] + n = s.getNode('strings') + if (not n.isSeq()): + print ('strings is not a sequence! FAIL', file=sys.stderr) + exit(1) + + for i in range(n.size()): + print (n.at(i).string()) + ## [readStr] + + ## [readMap] + n = s.getNode('Mapping') + print ('Two',int(n.getNode('Two').real()),'; ') + print ('One',int(n.getNode('One').real()),'\n') + ## [readMap] + + ## [iomat] + R = s.getNode('R_MAT').mat() + T = s.getNode('T_MAT').mat() + ## [iomat] + ## [customIO] + m.read(s.getNode('MyData')) + ## [customIO] + + print ('\nR =',R) + print ('T =',T,'\n') + print ('MyData =','\n',m,'\n') + + ## [nonexist] + print ('Attempt to read NonExisting (should initialize the data structure', + 'with its default).') + m.read(s.getNode('NonExisting')) + print ('\nNonExisting =','\n',m) + ## [nonexist] + + print ('\nTip: Open up',filename,'with a text editor to see the serialized data.') + +if __name__ == '__main__': + main(sys.argv)