nareshmlx/opencv-pr huggingface dataset:
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...

**Code Changes:**
```diff
@@ -71,33 +71,759 @@ minMaxIdx_( const T* src, const uchar* mask, WT* _minVal, WT* _maxVal,
     *_maxVal = maxVal;
 }
 
+#if CV_SIMD128
+template<typename T, typename WT> CV_ALWAYS_INLINE void
+minMaxIdx_init( const T* src, const uchar* mask, WT* minval, WT* maxval,
+                size_t* minidx, size_t* maxidx, WT &minVal, WT &maxVal,
+                size_t &minIdx, size_t &maxIdx, const WT minInit, const WT maxInit,
+                const int nlanes, int len, size_t startidx, int &j, int &len0 )
```

Review comment:
Sorry, missed that. However, e.g. for u8 there could be other case that won't be handled right: `minVal == -1; maxVal == 256;`
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...

**Code Changes:**
```diff
@@ -71,33 +71,759 @@ minMaxIdx_( const T* src, const uchar* mask, WT* _minVal, WT* _maxVal,
     *_maxVal = maxVal;
 }
 
+#if CV_SIMD128
+template<typename T, typename WT> CV_ALWAYS_INLINE void
+minMaxIdx_init( const T* src, const uchar* mask, WT* minval, WT* maxval,
+                size_t* minidx, size_t* maxidx, WT &minVal, WT &maxVal,
+                size_t &minIdx, size_t &maxIdx, const WT minInit, const WT maxInit,
+                const int nlanes, int len, size_t startidx, int &j, int &len0 )
```

Review comment:
RT could be deduced from VT as `typename VT::lane_type`. Comparison operator could be defined as template specialization for all necessary cases. Even if macro is used for that its size will be reduced essentially.
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...

**Code Changes:**
```diff
@@ -71,33 +71,759 @@ minMaxIdx_( const T* src, const uchar* mask, WT* _minVal, WT* _maxVal,
     *_maxVal = maxVal;
 }
 
+#if CV_SIMD128
+template<typename T, typename WT> CV_ALWAYS_INLINE void
+minMaxIdx_init( const T* src, const uchar* mask, WT* minval, WT* maxval,
+                size_t* minidx, size_t* maxidx, WT &minVal, WT &maxVal,
+                size_t &minIdx, size_t &maxIdx, const WT minInit, const WT maxInit,
+                const int nlanes, int len, size_t startidx, int &j, int &len0 )
```

Review comment:
I'll add 'minVal < minInit || maxVal > maxInit)
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...

**Code Changes:**
```diff
@@ -71,33 +71,759 @@ minMaxIdx_( const T* src, const uchar* mask, WT* _minVal, WT* _maxVal,
     *_maxVal = maxVal;
 }
 
+#if CV_SIMD128
+template<typename T, typename WT> CV_ALWAYS_INLINE void
+minMaxIdx_init( const T* src, const uchar* mask, WT* minval, WT* maxval,
+                size_t* minidx, size_t* maxidx, WT &minVal, WT &maxVal,
+                size_t &minIdx, size_t &maxIdx, const WT minInit, const WT maxInit,
+                const int nlanes, int len, size_t startidx, int &j, int &len0 )
```

Review comment:
I rewrote the reduce macro. It should evaluate in constant time now (probably faster as well). Can you rerun the timings again?
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...

**Code Changes:**
```diff
@@ -71,33 +71,759 @@ minMaxIdx_( const T* src, const uchar* mask, WT* _minVal, WT* _maxVal,
     *_maxVal = maxVal;
 }
 
+#if CV_SIMD128
+template<typename T, typename WT> CV_ALWAYS_INLINE void
+minMaxIdx_init( const T* src, const uchar* mask, WT* minval, WT* maxval,
+                size_t* minidx, size_t* maxidx, WT &minVal, WT &maxVal,
+                size_t &minIdx, size_t &maxIdx, const WT minInit, const WT maxInit,
+                const int nlanes, int len, size_t startidx, int &j, int &len0 )
```

Review comment:
I've prepared couple of changes for universal intrinsics #15538 #15541 that could simplify this code
**File:** modules/core/include/opencv2/core/hal/intrin_neon.hpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...
**Review Line:** 1245

**Code Changes:**
```diff
@@ -1241,6 +1241,20 @@ inline int v_reduce_sum(const v_int16x8& a)
     return vget_lane_s32(vpadd_s32(t1, t1), 0);
 }
 
+#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \
+inline scalartype v_reduce_##func(const _Tpvec& a) \
+{ \
+    _Tpnvec##_t a0 = vp##vectorfunc##_##suffix(vget_low_##suffix(a.val), vget_high_##suffix(a.val)); \
+    a0 = vp##vectorfunc##_##suffix(a0, a0); \
+    a0 = vp##vectorfunc##_##suffix(a0, a0); \
+    return (scalartype)vget_lane_##suffix(vp##vectorfunc##_##suffix(a0, a0),0); \
```

Review comment:
Documentation for v_reduce support matrix is [here]( https://github.com/opencv/opencv/blob/3.4.8/modules/core/include/opencv2/core/hal/intrin_cpp.hpp#L207). if you want to use them in OpenCV algorithms code, then corresponding documentation and intrinsic tests should be updated too.
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...

**Code Changes:**
```diff
@@ -71,33 +71,759 @@ minMaxIdx_( const T* src, const uchar* mask, WT* _minVal, WT* _maxVal,
     *_maxVal = maxVal;
 }
 
+#if CV_SIMD128
+template<typename T, typename WT> CV_ALWAYS_INLINE void
+minMaxIdx_init( const T* src, const uchar* mask, WT* minval, WT* maxval,
+                size_t* minidx, size_t* maxidx, WT &minVal, WT &maxVal,
+                size_t &minIdx, size_t &maxIdx, const WT minInit, const WT maxInit,
+                const int nlanes, int len, size_t startidx, int &j, int &len0 )
```

Review comment:
Please use this form: `j <= len0 - _uint16x8::nlanes` (used in many vectorized loops)
**File:** modules/core/include/opencv2/core/hal/intrin_cpp.hpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...

**Code Changes:**
```diff
@@ -205,7 +205,7 @@ Regular integers:
 |min, max           | x | x | x | x | x | x |
 |absdiff            | x | x | x | x | x | x |
 |absdiffs           |   | x |   | x |   |   |
-|reduce             |   |   |   |   | x | x |
+|reduce             | x | x | x | x | x | x |
 |mask               | x | x | x | x | x | x |
 |pack               | x | x | x | x | x | x |
 |pack_u             | x |   | x |   |   |   |
@@ -581,7 +581,7 @@ OPENCV_HAL_IMPL_MINMAX_FUNC(v_max, std::max)
```

Review comment:
64-bit floats are not supported too.
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...
**Review Line:** 727

**Code Changes:**
```diff
+                int k = j;
+                size_t delta = startidx + j;
+
+                if ( !mask )
+                {
+                    for( ; k < std::min(len0, j + 32764 * 4 * v_float64x2::nlanes); k += 4 * v_float64x2::nlanes )
+                    {
+                        v_float64x2 data = v_load(src + k);
+                        v_uint64x2 cmpMin = v_reinterpret_as_u64(data < valMin);
+                        v_uint64x2 cmpMax = v_reinterpret_as_u64(data > valMax);
+                        idxMin = v_select(cmpMin, idx, idxMin);
```

Review comment:
Why do we need x4 unrolling?
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...
**Review Line:** 727

**Code Changes:**
```diff
+                int k = j;
+                size_t delta = startidx + j;
+
+                if ( !mask )
+                {
+                    for( ; k < std::min(len0, j + 32764 * 4 * v_float64x2::nlanes); k += 4 * v_float64x2::nlanes )
+                    {
+                        v_float64x2 data = v_load(src + k);
+                        v_uint64x2 cmpMin = v_reinterpret_as_u64(data < valMin);
+                        v_uint64x2 cmpMax = v_reinterpret_as_u64(data > valMax);
+                        idxMin = v_select(cmpMin, idx, idxMin);
```

Review comment:
It makes it a lot easier to handle the 'mask' case down below (v_load_expand_q is really bad on some platforms).
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...
**Review Line:** 727

**Code Changes:**
```diff
+                int k = j;
+                size_t delta = startidx + j;
+
+                if ( !mask )
+                {
+                    for( ; k < std::min(len0, j + 32764 * 4 * v_float64x2::nlanes); k += 4 * v_float64x2::nlanes )
+                    {
+                        v_float64x2 data = v_load(src + k);
+                        v_uint64x2 cmpMin = v_reinterpret_as_u64(data < valMin);
+                        v_uint64x2 cmpMax = v_reinterpret_as_u64(data > valMax);
+                        idxMin = v_select(cmpMin, idx, idxMin);
```

Review comment:
This loop doesn't work this `mask`. Perhaps, loop below can be iterated over loaded `mask` size: ```.diff -4 * v_float64x2::nlanes +v_uint16x8::nlanes ``` with corresponding comment near "for" that loop iterations are performed over `mask` values.
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...
**Review Line:** 727

**Code Changes:**
```diff
+                int k = j;
+                size_t delta = startidx + j;
+
+                if ( !mask )
+                {
+                    for( ; k < std::min(len0, j + 32764 * 4 * v_float64x2::nlanes); k += 4 * v_float64x2::nlanes )
+                    {
+                        v_float64x2 data = v_load(src + k);
+                        v_uint64x2 cmpMin = v_reinterpret_as_u64(data < valMin);
+                        v_uint64x2 cmpMax = v_reinterpret_as_u64(data > valMax);
+                        idxMin = v_select(cmpMin, idx, idxMin);
```

Review comment:
I'd rather keep it the way it is for consistency with the other cases.
**File:** modules/core/include/opencv2/core/hal/intrin_neon.hpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...

**Code Changes:**
```diff
@@ -1241,6 +1241,20 @@ inline int v_reduce_sum(const v_int16x8& a)
     return vget_lane_s32(vpadd_s32(t1, t1), 0);
 }
 
+#define OPENCV_HAL_IMPL_NEON_REDUCE_OP_16(_Tpvec, _Tpnvec, scalartype, func, vectorfunc, suffix) \
+inline scalartype v_reduce_##func(const _Tpvec& a) \
+{ \
+    _Tpnvec##_t a0 = vp##vectorfunc##_##suffix(vget_low_##suffix(a.val), vget_high_##suffix(a.val)); \
+    a0 = vp##vectorfunc##_##suffix(a0, a0); \
+    a0 = vp##vectorfunc##_##suffix(a0, a0); \
```

Review comment:
IMO return type for min an max should be the same as lane type
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...
**Review Line:** 144

**Code Changes:**
```diff
+    return b ^ ((a ^ b) & mask);
+}
+#endif
+
+#define MINMAXIDX_REDUCE(suffix, suffix2, maxLimit, IR) \
+template<typename T, typename VT, typename IT> CV_ALWAYS_INLINE void \
+minMaxIdx_reduce_##suffix( VT &valMin, VT &valMax, IT &idxMin, IT &idxMax, IT &none, \
+                  T &minVal, T &maxVal, size_t &minIdx, size_t &maxIdx, \
+                  size_t delta ) \
+{ \
+    if ( v_check_any(idxMin != none) ) \
```

Review comment:
IMO template or macro is redundant here. If there was an opportunity to use something like `v_reinterpret_as_vectype<uchar>` instead of `v_reinterpret_as_u8` I would prefer template as a more debug friendly alternative. But at the moment it is impossible, so the macro looks like the only option. Also macro parameters could be reduced to `suffix2, VT, IT, T`. Something like that: ``` #define MINMAXIDX_REDUCE(suffix2, VT, IT, T) \ CV_ALWAYS_INLINE void minMaxIdx_reduce( VT &valMin, VT &valMax, IT &idxMin, IT &idxMax, IT &none, \ T &minVal, T &maxVal, size_t &minIdx, size_t &maxIdx, \ size_t delta ) \ { \ if ( v_check_any(idxMin != none) ) \ { \ minVal = v_reduce_min(valMin); \ minIdx = (size_t)v_reduce_min(v_select(v_reinterpret_as_##suffix2(v_setall((VT::lane_type)minVal) == valMin), \ idxMin, v_setall_##suffix2((IT::lane_type)-1))) + delta; \ } \ if ( v_check_any(idxMax != none) ) \ { \ maxVal = v_reduce_max(valMax); \ maxIdx = (size_t)v_reduce_min(v_select(v_reinterpret_as_##suffix2(v_setall((VT::lane_type)maxVal) == valMax), \ idxMax, v_setall_##suffix2((IT::lane_type)-1))) + delta; \ } \ } ```
**File:** modules/core/test/test_intrin_utils.hpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...

**Code Changes:**
```diff
@@ -853,13 +853,18 @@ template<typename R> struct TheTest
     TheTest & test_reduce()
     {
         Data<R> dataA;
+        int sum = 0;
+        for (int i = 0; i < R::nlanes; ++i)
+        {
+            sum += (int)(dataA[i]);   // To prevent a constant overflow with int8
+        }
         R a = dataA;
```

Review comment:
I think there should be cast to int rather than to LaneType to avoid overflow
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...
**Review Line:** 116

**Code Changes:**
```diff
+        len0 = j + ((len - j) & -nlanes);
+    }
+}
+
+#if CV_SIMD128_64F
+CV_ALWAYS_INLINE double v_reduce_min(const v_float64x2& a)
+{
+    double CV_DECL_ALIGNED(32) idx[2];
+    v_store_aligned(idx, a);
+    return std::min(idx[0], idx[1]);
+}
```

Review comment:
IMO it would be better to extend the overall set of intrinsics
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...
**Review Line:** 116

**Code Changes:**
```diff
+        len0 = j + ((len - j) & -nlanes);
+    }
+}
+
+#if CV_SIMD128_64F
+CV_ALWAYS_INLINE double v_reduce_min(const v_float64x2& a)
+{
+    double CV_DECL_ALIGNED(32) idx[2];
+    v_store_aligned(idx, a);
+    return std::min(idx[0], idx[1]);
+}
```

Review comment:
I think until the intrinsics for all the platforms use v_float64x2 and v_uint64x2 more fully, this is a better approach.
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...
**Review Line:** 144

**Code Changes:**
```diff
+    return b ^ ((a ^ b) & mask);
+}
+#endif
+
+#define MINMAXIDX_REDUCE(suffix, suffix2, maxLimit, IR) \
+template<typename T, typename VT, typename IT> CV_ALWAYS_INLINE void \
+minMaxIdx_reduce_##suffix( VT &valMin, VT &valMax, IT &idxMin, IT &idxMax, IT &none, \
+                  T &minVal, T &maxVal, size_t &minIdx, size_t &maxIdx, \
+                  size_t delta ) \
+{ \
+    if ( v_check_any(idxMin != none) ) \
```

Review comment:
This is not the same - some types (float and double) do NOT use max as -1
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...
**Review Line:** 144

**Code Changes:**
```diff
+    return b ^ ((a ^ b) & mask);
+}
+#endif
+
+#define MINMAXIDX_REDUCE(suffix, suffix2, maxLimit, IR) \
+template<typename T, typename VT, typename IT> CV_ALWAYS_INLINE void \
+minMaxIdx_reduce_##suffix( VT &valMin, VT &valMax, IT &idxMin, IT &idxMax, IT &none, \
+                  T &minVal, T &maxVal, size_t &minIdx, size_t &maxIdx, \
+                  size_t delta ) \
+{ \
+    if ( v_check_any(idxMin != none) ) \
```

Review comment:
As far as I could understand this value is used as "do not select" value, to restrict result of the following `v_reduce_min` to indexes of valid search results only. So I don't see the reason that denies replacement of this value by greater one. Could you please share your thoughts on this?
**File:** modules/core/test/test_intrin_utils.hpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...

**Code Changes:**
```diff
@@ -853,13 +853,18 @@ template<typename R> struct TheTest
     TheTest & test_reduce()
     {
         Data<R> dataA;
+        int sum = 0;
+        for (int i = 0; i < R::nlanes; ++i)
+        {
+            sum += (int)(dataA[i]);   // To prevent a constant overflow with int8
+        }
         R a = dataA;
```

Review comment:
I mean `v_reduce_sum` only. It's fine to have `LaneType` for other reductions since they return value is already of `LaneType`
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...
**Review Line:** 144

**Code Changes:**
```diff
+    return b ^ ((a ^ b) & mask);
+}
+#endif
+
+#define MINMAXIDX_REDUCE(suffix, suffix2, maxLimit, IR) \
+template<typename T, typename VT, typename IT> CV_ALWAYS_INLINE void \
+minMaxIdx_reduce_##suffix( VT &valMin, VT &valMax, IT &idxMin, IT &idxMax, IT &none, \
+                  T &minVal, T &maxVal, size_t &minIdx, size_t &maxIdx, \
+                  size_t delta ) \
+{ \
+    if ( v_check_any(idxMin != none) ) \
```

Review comment:
This code is used to create a position location of the min or max that can never occur. Your code could be creating NANs for non-integer types. Use of NANs can be unpredictable.
**File:** modules/core/src/minmax.cpp
**Change Type:** modified
**Context:** PR #15488: Vectorize minMaxIdx functions - Vectorize minMaxIdx functions. minMaxIdx_8u & minMaxIdx_8s - 11.1x improvement on VSX and 8.6x speedup on x...
**Review Line:** 144

**Code Changes:**
```diff
+    return b ^ ((a ^ b) & mask);
+}
+#endif
+
+#define MINMAXIDX_REDUCE(suffix, suffix2, maxLimit, IR) \
+template<typename T, typename VT, typename IT> CV_ALWAYS_INLINE void \
+minMaxIdx_reduce_##suffix( VT &valMin, VT &valMax, IT &idxMin, IT &idxMax, IT &none, \
+                  T &minVal, T &maxVal, size_t &minIdx, size_t &maxIdx, \
+                  size_t delta ) \
+{ \
+    if ( v_check_any(idxMin != none) ) \
```

Review comment:
Position location types are unsigned integers of different width for all existing instantiations. I doubt that floating point types could be used for that somewhere in the future but anyway such a change will require update of the whole algorithm since `idxMax` still could contain not yet updated parts of the initial `none` value which also should be treated as NaN's in that case
**File:** samples/python/text_skewness_correction.py
**Change Type:** added
**Context:** PR #16170: added tutorial for text skewness correction -  ### This pull request changes Given an image containing a rotated block of text at an unknow...

**Code Changes:**
```diff
@@ -0,0 +1,58 @@
+'''
+Text skewness correction
+This tutorial demonstrates how to correct the skewness in a text.
+The program takes as input a skewed source image and shows non skewed text.
+
+Usage:
+        python text_skewness_correction.py --image "Image path"
+'''
+
```

Review comment:
Please add extra line to separate main function from entry point.
**File:** samples/python/text_skewness_correction.py
**Change Type:** added
**Context:** PR #16170: added tutorial for text skewness correction -  ### This pull request changes Given an image containing a rotated block of text at an unknow...

**Code Changes:**
```diff
@@ -0,0 +1,58 @@
+'''
+Text skewness correction
+This tutorial demonstrates how to correct the skewness in a text.
+The program takes as input a skewed source image and shows non skewed text.
+
+Usage:
+        python text_skewness_correction.py --image "Image path"
+'''
+
```

Review comment:
You have to rebase your changes to 3.4 with git command `git rebase -i --onto upstream/3.4 upstream/master` as I mentioned before and then push branch with force option to re-write commits history.
**File:** samples/python/text_skewness_correction.py
**Change Type:** added
**Context:** PR #16170: added tutorial for text skewness correction -  ### This pull request changes Given an image containing a rotated block of text at an unknow...

**Code Changes:**
```diff
@@ -0,0 +1,58 @@
+'''
+Text skewness correction
+This tutorial demonstrates how to correct the skewness in a text.
+The program takes as input a skewed source image and shows non skewed text.
+
+Usage:
+        python text_skewness_correction.py --image "Image path"
+'''
+
```

Review comment:
I followed the method and changed it but I don't know why so many commits are visible here I tried to reset the branch to the previous commit but still, I can see these commits also the merge is failing
**File:** samples/python/text_skewness_correction.py
**Change Type:** added
**Context:** PR #16170: added tutorial for text skewness correction -  ### This pull request changes Given an image containing a rotated block of text at an unknow...

**Code Changes:**
```diff
@@ -0,0 +1,58 @@
+'''
+Text skewness correction
+This tutorial demonstrates how to correct the skewness in a text.
+The program takes as input a skewed source image and shows non skewed text.
+
+Usage:
+        python text_skewness_correction.py --image "Image path"
+'''
+
```

Review comment:
It's better to move it on top to have all imports in one place.
**File:** samples/cpp/text_skewness_correction.cpp
**Change Type:** added
**Context:** PR #16170: added tutorial for text skewness correction -  ### This pull request changes Given an image containing a rotated block of text at an unknow...

**Code Changes:**
```diff
@@ -0,0 +1,74 @@
+/*
+This tutorial demonstrates how to correct the skewness in a text.
+The program takes as input a skewed source image and shows non skewed text.
+
+*/
+
+#include <opencv2/core.hpp>
+#include <opencv2/imgcodecs.hpp>
+#include <opencv2/highgui.hpp>
```

Review comment:
you can remove this line and use `threshold(gray, thresh, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);` below