diff --git a/doc/_themes/blue/layout.html b/doc/_themes/blue/layout.html
index 5bc9c86003..8bba49b17a 100644
--- a/doc/_themes/blue/layout.html
+++ b/doc/_themes/blue/layout.html
@@ -188,7 +188,7 @@
{% if theme_lang == 'py' %}
Try the Cookbook.
{% endif %}
- Ask a question in the user group/mailing list.
+ Ask a question on the Q&A forum.
If you think something is missing or wrong in the documentation,
please file a bug report.
diff --git a/modules/core/src/arithm.cpp b/modules/core/src/arithm.cpp
index 130d3fafa0..10ca872a98 100644
--- a/modules/core/src/arithm.cpp
+++ b/modules/core/src/arithm.cpp
@@ -1218,28 +1218,21 @@ namespace cv
static int actualScalarDepth(const double* data, int len)
{
- double minval = data[0];
- double maxval = data[0];
- for(int i = 1; i < len; ++i)
- {
- minval = MIN(minval, data[i]);
- maxval = MAX(maxval, data[i]);
- }
-
- int depth = CV_64F;
- if(minval >= 0 && maxval <= UCHAR_MAX)
- depth = CV_8U;
- else if(minval >= SCHAR_MIN && maxval <= SCHAR_MAX)
- depth = CV_8S;
- else if(minval >= 0 && maxval <= USHRT_MAX)
- depth = CV_16U;
- else if(minval >= SHRT_MIN && maxval <= SHRT_MAX)
- depth = CV_16S;
- else if(minval >= INT_MIN && maxval <= INT_MAX)
- depth = CV_32S;
- else if(minval >= -FLT_MAX && maxval <= FLT_MAX)
- depth = CV_32F;
- return depth;
+ int i = 0, minval = INT_MAX, maxval = INT_MIN;
+ for(; i < len; ++i)
+ {
+ int ival = cvRound(data[i]);
+ if( ival != data[i] )
+ break;
+ minval = MIN(minval, ival);
+ maxval = MAX(maxval, ival);
+ }
+ return i < len ? CV_64F :
+ minval >= 0 && maxval <= UCHAR_MAX ? CV_8U :
+ minval >= SCHAR_MIN && maxval <= SCHAR_MAX ? CV_8S :
+ minval >= 0 && maxval <= USHRT_MAX ? CV_16U :
+ minval >= SHRT_MIN && maxval <= SHRT_MAX ? CV_16S :
+ CV_32S;
}
static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
@@ -1264,7 +1257,9 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
bool haveScalar = false, swapped12 = false;
int depth2 = src2.depth();
- if( src1.size != src2.size || src1.channels() != src2.channels() )
+ if( src1.size != src2.size || src1.channels() != src2.channels() ||
+ ((kind1 == _InputArray::MATX || kind2 == _InputArray::MATX) &&
+ src1.cols == 1 && src2.rows == 4) )
{
if( checkScalar(src1, src2.type(), kind1, kind2) )
{
@@ -1279,10 +1274,14 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
haveScalar = true;
CV_Assert(src2.type() == CV_64F && (src2.rows == 4 || src2.rows == 1));
- if (usrdata == 0) // hack to filter out multiply and divide
+ if (!muldiv)
+ {
depth2 = actualScalarDepth(src2.ptr(), src1.channels());
+ if( depth2 == CV_64F && (src1.depth() < CV_32S || src1.depth() == CV_32F) )
+ depth2 = CV_32F;
+ }
else
- depth2 = CV_64F;
+ depth2 = src1.depth() < CV_32S || src1.depth() == CV_32F ? CV_32F : CV_64F;
}
int cn = src1.channels(), depth1 = src1.depth(), wtype;
diff --git a/modules/core/src/parallel.cpp b/modules/core/src/parallel.cpp
index 87bfbe9f5e..5a17c95a43 100644
--- a/modules/core/src/parallel.cpp
+++ b/modules/core/src/parallel.cpp
@@ -42,6 +42,17 @@
#include "precomp.hpp"
+#if defined __linux__ || defined __APPLE__
+ #include
+ #include
+ #include
+ #if defined ANDROID
+ #include
+ #else
+ #include
+ #endif
+#endif
+
#ifdef _OPENMP
#define HAVE_OPENMP
#endif
@@ -85,7 +96,6 @@
#include
#elif defined HAVE_GCD
#include
- #include
#include
#elif defined HAVE_CONCURRENCY
#include
diff --git a/modules/core/test/test_operations.cpp b/modules/core/test/test_operations.cpp
index edc9633af8..2e4714639c 100644
--- a/modules/core/test/test_operations.cpp
+++ b/modules/core/test/test_operations.cpp
@@ -76,6 +76,7 @@ protected:
bool TestVec();
bool TestMatxMultiplication();
bool TestSubMatAccess();
+ bool TestExp();
bool TestSVD();
bool operations1();
@@ -1003,6 +1004,17 @@ bool CV_OperationsTest::operations1()
}
+bool CV_OperationsTest::TestExp()
+{
+ Mat1f tt = Mat1f::ones(4,2);
+ Mat1f outs;
+ exp(-tt, outs);
+ Mat1f tt2 = Mat1f::ones(4,1), outs2;
+ exp(-tt2, outs2);
+ return true;
+}
+
+
bool CV_OperationsTest::TestSVD()
{
try
@@ -1079,6 +1091,9 @@ void CV_OperationsTest::run( int /* start_from */)
if (!TestSubMatAccess())
return;
+ if (!TestExp())
+ return;
+
if (!TestSVD())
return;
diff --git a/modules/gpu/src/cuda/column_filter.cu b/modules/gpu/src/cuda/column_filter.cu
index d3c3ca6f7e..af7369ad5e 100644
--- a/modules/gpu/src/cuda/column_filter.cu
+++ b/modules/gpu/src/cuda/column_filter.cu
@@ -377,10 +377,13 @@ namespace cv { namespace gpu { namespace device
}
template void linearColumnFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
+ template void linearColumnFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearColumnFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearColumnFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearColumnFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearColumnFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
+ template void linearColumnFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
+ template void linearColumnFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
} // namespace column_filter
}}} // namespace cv { namespace gpu { namespace device
diff --git a/modules/gpu/src/cuda/row_filter.cu b/modules/gpu/src/cuda/row_filter.cu
index 7fdbee6cdc..39fc53fdc4 100644
--- a/modules/gpu/src/cuda/row_filter.cu
+++ b/modules/gpu/src/cuda/row_filter.cu
@@ -376,10 +376,13 @@ namespace cv { namespace gpu { namespace device
}
template void linearRowFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
+ template void linearRowFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearRowFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearRowFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearRowFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
template void linearRowFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
+ template void linearRowFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
+ template void linearRowFilter_gpu(PtrStepSzb src, PtrStepSzb dst, const float* kernel, int ksize, int anchor, int brd_type, int cc, cudaStream_t stream);
} // namespace row_filter
}}} // namespace cv { namespace gpu { namespace device
diff --git a/modules/gpu/src/filtering.cpp b/modules/gpu/src/filtering.cpp
index c34a97ff40..77ed46e159 100644
--- a/modules/gpu/src/filtering.cpp
+++ b/modules/gpu/src/filtering.cpp
@@ -922,7 +922,7 @@ Ptr cv::gpu::getLinearRowFilter_GPU(int srcType, int bufType,
int gpuBorderType;
CV_Assert(tryConvertToGpuBorderType(borderType, gpuBorderType));
- CV_Assert(srcType == CV_8UC1 || srcType == CV_8UC4 || srcType == CV_16SC3 || srcType == CV_32SC1 || srcType == CV_32FC1);
+ CV_Assert(srcType == CV_8UC1 || srcType == CV_8UC3 || srcType == CV_8UC4 || srcType == CV_16SC3 || srcType == CV_32SC1 || srcType == CV_32FC1 || srcType == CV_32FC3 || srcType == CV_32FC4);
CV_Assert(CV_MAT_DEPTH(bufType) == CV_32F && CV_MAT_CN(srcType) == CV_MAT_CN(bufType));
@@ -942,6 +942,9 @@ Ptr cv::gpu::getLinearRowFilter_GPU(int srcType, int bufType,
case CV_8UC1:
func = linearRowFilter_gpu;
break;
+ case CV_8UC3:
+ func = linearRowFilter_gpu;
+ break;
case CV_8UC4:
func = linearRowFilter_gpu;
break;
@@ -954,6 +957,12 @@ Ptr cv::gpu::getLinearRowFilter_GPU(int srcType, int bufType,
case CV_32FC1:
func = linearRowFilter_gpu;
break;
+ case CV_32FC3:
+ func = linearRowFilter_gpu;
+ break;
+ case CV_32FC4:
+ func = linearRowFilter_gpu;
+ break;
}
return Ptr(new GpuLinearRowFilter(ksize, anchor, gpu_row_krnl, func, gpuBorderType));
@@ -1034,7 +1043,7 @@ Ptr cv::gpu::getLinearColumnFilter_GPU(int bufType, int ds
int gpuBorderType;
CV_Assert(tryConvertToGpuBorderType(borderType, gpuBorderType));
- CV_Assert(dstType == CV_8UC1 || dstType == CV_8UC4 || dstType == CV_16SC3 || dstType == CV_32SC1 || dstType == CV_32FC1);
+ CV_Assert(dstType == CV_8UC1 || dstType == CV_8UC3 || dstType == CV_8UC4 || dstType == CV_16SC3 || dstType == CV_32SC1 || dstType == CV_32FC1 || dstType == CV_32FC3 || dstType == CV_32FC4);
CV_Assert(CV_MAT_DEPTH(bufType) == CV_32F && CV_MAT_CN(dstType) == CV_MAT_CN(bufType));
@@ -1054,6 +1063,9 @@ Ptr cv::gpu::getLinearColumnFilter_GPU(int bufType, int ds
case CV_8UC1:
func = linearColumnFilter_gpu;
break;
+ case CV_8UC3:
+ func = linearColumnFilter_gpu;
+ break;
case CV_8UC4:
func = linearColumnFilter_gpu;
break;
@@ -1066,6 +1078,12 @@ Ptr cv::gpu::getLinearColumnFilter_GPU(int bufType, int ds
case CV_32FC1:
func = linearColumnFilter_gpu;
break;
+ case CV_32FC3:
+ func = linearColumnFilter_gpu;
+ break;
+ case CV_32FC4:
+ func = linearColumnFilter_gpu;
+ break;
}
return Ptr(new GpuLinearColumnFilter(ksize, anchor, gpu_col_krnl, func, gpuBorderType));
diff --git a/modules/gpu/test/test_filters.cpp b/modules/gpu/test/test_filters.cpp
index dddca15702..bb070373e4 100644
--- a/modules/gpu/test/test_filters.cpp
+++ b/modules/gpu/test/test_filters.cpp
@@ -152,13 +152,13 @@ TEST_P(Sobel, Accuracy)
cv::Mat dst_gold;
cv::Sobel(src, dst_gold, -1, dx, dy, ksize.width, 1.0, 0.0, borderType);
- EXPECT_MAT_NEAR(dst_gold, dst, 0.0);
+ EXPECT_MAT_NEAR(dst_gold, dst, CV_MAT_DEPTH(type) < CV_32F ? 0.0 : 0.1);
}
INSTANTIATE_TEST_CASE_P(GPU_Filter, Sobel, testing::Combine(
ALL_DEVICES,
DIFFERENT_SIZES,
- testing::Values(MatType(CV_8UC1), MatType(CV_8UC4)),
+ testing::Values(MatType(CV_8UC1), MatType(CV_8UC3), MatType(CV_8UC4), MatType(CV_32FC1), MatType(CV_32FC3), MatType(CV_32FC4)),
testing::Values(KSize(cv::Size(3, 3)), KSize(cv::Size(5, 5)), KSize(cv::Size(7, 7))),
testing::Values(Deriv_X(0), Deriv_X(1), Deriv_X(2)),
testing::Values(Deriv_Y(0), Deriv_Y(1), Deriv_Y(2)),
@@ -208,13 +208,13 @@ TEST_P(Scharr, Accuracy)
cv::Mat dst_gold;
cv::Scharr(src, dst_gold, -1, dx, dy, 1.0, 0.0, borderType);
- EXPECT_MAT_NEAR(dst_gold, dst, 0.0);
+ EXPECT_MAT_NEAR(dst_gold, dst, CV_MAT_DEPTH(type) < CV_32F ? 0.0 : 0.1);
}
INSTANTIATE_TEST_CASE_P(GPU_Filter, Scharr, testing::Combine(
ALL_DEVICES,
DIFFERENT_SIZES,
- testing::Values(MatType(CV_8UC1), MatType(CV_8UC4)),
+ testing::Values(MatType(CV_8UC1), MatType(CV_8UC3), MatType(CV_8UC4), MatType(CV_32FC1), MatType(CV_32FC3), MatType(CV_32FC4)),
testing::Values(Deriv_X(0), Deriv_X(1)),
testing::Values(Deriv_Y(0), Deriv_Y(1)),
testing::Values(BorderType(cv::BORDER_REFLECT101),
@@ -281,7 +281,7 @@ TEST_P(GaussianBlur, Accuracy)
INSTANTIATE_TEST_CASE_P(GPU_Filter, GaussianBlur, testing::Combine(
ALL_DEVICES,
DIFFERENT_SIZES,
- testing::Values(MatType(CV_8UC1), MatType(CV_8UC4)),
+ testing::Values(MatType(CV_8UC1), MatType(CV_8UC3), MatType(CV_8UC4), MatType(CV_32FC1), MatType(CV_32FC3), MatType(CV_32FC4)),
testing::Values(KSize(cv::Size(3, 3)),
KSize(cv::Size(5, 5)),
KSize(cv::Size(7, 7)),
diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp
index a67099d468..6d9a984290 100644
--- a/modules/imgproc/src/imgwarp.cpp
+++ b/modules/imgproc/src/imgwarp.cpp
@@ -221,6 +221,18 @@ static const void* initInterTab2D( int method, bool fixpt )
}
+static bool initAllInterTab2D()
+{
+ return initInterTab2D( INTER_LINEAR, false ) &&
+ initInterTab2D( INTER_LINEAR, true ) &&
+ initInterTab2D( INTER_CUBIC, false ) &&
+ initInterTab2D( INTER_CUBIC, true ) &&
+ initInterTab2D( INTER_LANCZOS4, false ) &&
+ initInterTab2D( INTER_LANCZOS4, true );
+}
+
+static volatile bool doInitAllInterTab2D = initAllInterTab2D();
+
template struct Cast
{
typedef ST type1;
@@ -1390,172 +1402,150 @@ struct DecimateAlpha
float alpha;
};
-template
-class resizeArea_Invoker :
+
+template class ResizeArea_Invoker :
public ParallelLoopBody
{
public:
- resizeArea_Invoker(const Mat& _src, Mat& _dst, const DecimateAlpha* _xofs,
- int _xofs_count, double _scale_y_, const int* _cur_dy_ofs,
- const std::vector >& _bands) :
- ParallelLoopBody(), src(_src), dst(_dst), xofs(_xofs),
- xofs_count(_xofs_count), scale_y_(_scale_y_),
- cur_dy_ofs(_cur_dy_ofs), bands(_bands)
+ ResizeArea_Invoker( const Mat& _src, Mat& _dst,
+ const DecimateAlpha* _xtab, int _xtab_size,
+ const DecimateAlpha* _ytab, int _ytab_size,
+ const int* _tabofs )
{
+ src = &_src;
+ dst = &_dst;
+ xtab0 = _xtab;
+ xtab_size0 = _xtab_size;
+ ytab = _ytab;
+ ytab_size = _ytab_size;
+ tabofs = _tabofs;
}
- void resize_single_band(const Range& range) const
+ virtual void operator() (const Range& range) const
{
- Size ssize = src.size(), dsize = dst.size();
- int cn = src.channels();
+ Size dsize = dst->size();
+ int cn = dst->channels();
dsize.width *= cn;
AutoBuffer _buffer(dsize.width*2);
+ const DecimateAlpha* xtab = xtab0;
+ int xtab_size = xtab_size0;
WT *buf = _buffer, *sum = buf + dsize.width;
- int k = 0, sy = 0, dx = 0, cur_dy = 0;
- WT scale_y = (WT)scale_y_;
+ int j_start = tabofs[range.start], j_end = tabofs[range.end], j, k, dx, prev_dy = ytab[j_start].di;
- CV_Assert( cn <= 4 );
for( dx = 0; dx < dsize.width; dx++ )
- buf[dx] = sum[dx] = 0;
+ sum[dx] = (WT)0;
- cur_dy = cur_dy_ofs[range.start];
- for (sy = range.start; sy < range.end; sy++)
+ for( j = j_start; j < j_end; j++ )
{
- const T* S = (const T*)(src.data + src.step*sy);
- if( cn == 1 )
- for( k = 0; k < xofs_count; k++ )
- {
- int dxn = xofs[k].di;
- WT alpha = xofs[k].alpha;
- buf[dxn] += S[xofs[k].si]*alpha;
- }
- else if( cn == 2 )
- for( k = 0; k < xofs_count; k++ )
- {
- int sxn = xofs[k].si;
- int dxn = xofs[k].di;
- WT alpha = xofs[k].alpha;
- WT t0 = buf[dxn] + S[sxn]*alpha;
- WT t1 = buf[dxn+1] + S[sxn+1]*alpha;
- buf[dxn] = t0; buf[dxn+1] = t1;
- }
- else if( cn == 3 )
- for( k = 0; k < xofs_count; k++ )
- {
- int sxn = xofs[k].si;
- int dxn = xofs[k].di;
- WT alpha = xofs[k].alpha;
- WT t0 = buf[dxn] + S[sxn]*alpha;
- WT t1 = buf[dxn+1] + S[sxn+1]*alpha;
- WT t2 = buf[dxn+2] + S[sxn+2]*alpha;
- buf[dxn] = t0; buf[dxn+1] = t1; buf[dxn+2] = t2;
- }
- else
- for( k = 0; k < xofs_count; k++ )
- {
- int sxn = xofs[k].si;
- int dxn = xofs[k].di;
- WT alpha = xofs[k].alpha;
- WT t0 = buf[dxn] + S[sxn]*alpha;
- WT t1 = buf[dxn+1] + S[sxn+1]*alpha;
- buf[dxn] = t0; buf[dxn+1] = t1;
- t0 = buf[dxn+2] + S[sxn+2]*alpha;
- t1 = buf[dxn+3] + S[sxn+3]*alpha;
- buf[dxn+2] = t0; buf[dxn+3] = t1;
- }
+ WT beta = ytab[j].alpha;
+ int dy = ytab[j].di;
+ int sy = ytab[j].si;
- if( (cur_dy + 1)*scale_y <= sy + 1 || sy == ssize.height - 1 )
{
- WT beta = std::max(sy + 1 - (cur_dy+1)*scale_y, (WT)0);
- WT beta1 = 1 - beta;
- T* D = (T*)(dst.data + dst.step*cur_dy);
- if( fabs(beta) < 1e-3 )
+ const T* S = (const T*)(src->data + src->step*sy);
+ for( dx = 0; dx < dsize.width; dx++ )
+ buf[dx] = (WT)0;
+
+ if( cn == 1 )
+ for( k = 0; k < xtab_size; k++ )
+ {
+ int dxn = xtab[k].di;
+ WT alpha = xtab[k].alpha;
+ buf[dxn] += S[xtab[k].si]*alpha;
+ }
+ else if( cn == 2 )
+ for( k = 0; k < xtab_size; k++ )
+ {
+ int sxn = xtab[k].si;
+ int dxn = xtab[k].di;
+ WT alpha = xtab[k].alpha;
+ WT t0 = buf[dxn] + S[sxn]*alpha;
+ WT t1 = buf[dxn+1] + S[sxn+1]*alpha;
+ buf[dxn] = t0; buf[dxn+1] = t1;
+ }
+ else if( cn == 3 )
+ for( k = 0; k < xtab_size; k++ )
+ {
+ int sxn = xtab[k].si;
+ int dxn = xtab[k].di;
+ WT alpha = xtab[k].alpha;
+ WT t0 = buf[dxn] + S[sxn]*alpha;
+ WT t1 = buf[dxn+1] + S[sxn+1]*alpha;
+ WT t2 = buf[dxn+2] + S[sxn+2]*alpha;
+ buf[dxn] = t0; buf[dxn+1] = t1; buf[dxn+2] = t2;
+ }
+ else if( cn == 4 )
{
- if(cur_dy >= dsize.height)
- return;
- for( dx = 0; dx < dsize.width; dx++ )
+ for( k = 0; k < xtab_size; k++ )
{
- D[dx] = saturate_cast((sum[dx] + buf[dx]) / min(scale_y, src.rows - cur_dy * scale_y)); //
- sum[dx] = buf[dx] = 0;
+ int sxn = xtab[k].si;
+ int dxn = xtab[k].di;
+ WT alpha = xtab[k].alpha;
+ WT t0 = buf[dxn] + S[sxn]*alpha;
+ WT t1 = buf[dxn+1] + S[sxn+1]*alpha;
+ buf[dxn] = t0; buf[dxn+1] = t1;
+ t0 = buf[dxn+2] + S[sxn+2]*alpha;
+ t1 = buf[dxn+3] + S[sxn+3]*alpha;
+ buf[dxn+2] = t0; buf[dxn+3] = t1;
}
}
else
- for( dx = 0; dx < dsize.width; dx++ )
+ {
+ for( k = 0; k < xtab_size; k++ )
{
- D[dx] = saturate_cast((sum[dx] + buf[dx]* beta1)/ min(scale_y, src.rows - cur_dy*scale_y)); //
- sum[dx] = buf[dx]*beta;
- buf[dx] = 0;
+ int sxn = xtab[k].si;
+ int dxn = xtab[k].di;
+ WT alpha = xtab[k].alpha;
+ for( int c = 0; c < cn; c++ )
+ buf[dxn + c] += S[sxn + c]*alpha;
}
- cur_dy++;
+ }
}
- else
+
+ if( dy != prev_dy )
{
- for( dx = 0; dx <= dsize.width - 2; dx += 2 )
- {
- WT t0 = sum[dx] + buf[dx];
- WT t1 = sum[dx+1] + buf[dx+1];
- sum[dx] = t0; sum[dx+1] = t1;
- buf[dx] = buf[dx+1] = 0;
- }
- for( ; dx < dsize.width; dx++ )
+ T* D = (T*)(dst->data + dst->step*prev_dy);
+
+ for( dx = 0; dx < dsize.width; dx++ )
{
- sum[dx] += buf[dx];
- buf[dx] = 0;
+ D[dx] = saturate_cast(sum[dx]);
+ sum[dx] = beta*buf[dx];
}
+ prev_dy = dy;
+ }
+ else
+ {
+ for( dx = 0; dx < dsize.width; dx++ )
+ sum[dx] += beta*buf[dx];
}
}
- }
- virtual void operator() (const Range& range) const
- {
- for (int i = range.start; i < range.end; ++i)
{
- Range band_range(bands[i].first, bands[i].second);
- resize_single_band(band_range);
+ T* D = (T*)(dst->data + dst->step*prev_dy);
+ for( dx = 0; dx < dsize.width; dx++ )
+ D[dx] = saturate_cast(sum[dx]);
}
}
private:
- Mat src;
- Mat dst;
- const DecimateAlpha* xofs;
- int xofs_count;
- double scale_y_;
- const int *cur_dy_ofs;
- std::vector > bands;
+ const Mat* src;
+ Mat* dst;
+ const DecimateAlpha* xtab0;
+ const DecimateAlpha* ytab;
+ int xtab_size0, ytab_size;
+ const int* tabofs;
};
-template
-static void resizeArea_( const Mat& src, Mat& dst, const DecimateAlpha* xofs, int xofs_count, double scale_y_)
-{
- Size ssize = src.size(), dsize = dst.size();
- AutoBuffer _yofs(ssize.height);
- int *cur_dy_ofs = _yofs;
- int cur_dy = 0, index = 0;
- std::vector > bands;
-
- for (int sy = 0; sy < ssize.height; sy++)
- {
- cur_dy_ofs[sy] = cur_dy;
-
- if ((cur_dy + 1) * scale_y_ <= sy + 1 || sy == ssize.height - 1 )
- {
- WT beta = (WT)std::max(sy + 1 - (cur_dy + 1) * scale_y_, 0.);
- if (fabs(beta) < 1e-3 )
- {
- if (cur_dy >= dsize.height)
- break;
- bands.push_back(std::make_pair(index, sy + 1));
- index = sy + 1;
- }
- cur_dy++;
- }
- }
- Range range(0, (int)bands.size());
- resizeArea_Invoker invoker(src, dst, xofs, xofs_count, scale_y_, cur_dy_ofs, bands);
- //parallel_for_(range, invoker);
- invoker(Range(range.start, range.end));
+template
+static void resizeArea_( const Mat& src, Mat& dst,
+ const DecimateAlpha* xtab, int xtab_size,
+ const DecimateAlpha* ytab, int ytab_size,
+ const int* tabofs )
+{
+ parallel_for_(Range(0, dst.rows),
+ ResizeArea_Invoker(src, dst, xtab, xtab_size, ytab, ytab_size, tabofs),
+ dst.total()/((double)(1 << 16)));
}
@@ -1569,8 +1559,52 @@ typedef void (*ResizeAreaFastFunc)( const Mat& src, Mat& dst,
int scale_x, int scale_y );
typedef void (*ResizeAreaFunc)( const Mat& src, Mat& dst,
- const DecimateAlpha* xofs, int xofs_count,
- double scale_y_);
+ const DecimateAlpha* xtab, int xtab_size,
+ const DecimateAlpha* ytab, int ytab_size,
+ const int* yofs);
+
+
+static int computeResizeAreaTab( int ssize, int dsize, int cn, double scale, DecimateAlpha* tab )
+{
+ int k = 0;
+ for(int dx = 0; dx < dsize; dx++ )
+ {
+ double fsx1 = dx * scale;
+ double fsx2 = fsx1 + scale;
+ double cellWidth = min(scale, ssize - fsx1);
+
+ int sx1 = cvCeil(fsx1), sx2 = cvFloor(fsx2);
+
+ sx2 = std::min(sx2, ssize - 1);
+ sx1 = std::min(sx1, sx2);
+
+ if( sx1 - fsx1 > 1e-3 )
+ {
+ assert( k < ssize*2 );
+ tab[k].di = dx * cn;
+ tab[k].si = (sx1 - 1) * cn;
+ tab[k++].alpha = (float)((sx1 - fsx1) / cellWidth);
+ }
+
+ for(int sx = sx1; sx < sx2; sx++ )
+ {
+ assert( k < ssize*2 );
+ tab[k].di = dx * cn;
+ tab[k].si = sx * cn;
+ tab[k++].alpha = float(1.0 / cellWidth);
+ }
+
+ if( fsx2 - sx2 > 1e-3 )
+ {
+ assert( k < ssize*2 );
+ tab[k].di = dx * cn;
+ tab[k].si = sx2 * cn;
+ tab[k++].alpha = (float)(min(min(fsx2 - sx2, 1.), cellWidth) / cellWidth);
+ }
+ }
+ return k;
+}
+
}
@@ -1766,43 +1800,25 @@ void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
ResizeAreaFunc func = area_tab[depth];
CV_Assert( func != 0 && cn <= 4 );
- AutoBuffer _xofs(ssize.width*2);
- DecimateAlpha* xofs = _xofs;
-
- for( dx = 0, k = 0; dx < dsize.width; dx++ )
- {
- double fsx1 = dx*scale_x;
- double fsx2 = fsx1 + scale_x;
- int sx1 = cvCeil(fsx1), sx2 = cvFloor(fsx2);
- sx1 = std::min(sx1, ssize.width-1);
- sx2 = std::min(sx2, ssize.width-1);
-
- if( sx1 > fsx1 )
- {
- assert( k < ssize.width*2 );
- xofs[k].di = dx*cn;
- xofs[k].si = (sx1-1)*cn;
- xofs[k++].alpha = (float)((sx1 - fsx1) / min(scale_x, src.cols - fsx1));
- }
+ AutoBuffer _xytab((ssize.width + ssize.height)*2);
+ DecimateAlpha* xtab = _xytab, *ytab = xtab + ssize.width*2;
- for( sx = sx1; sx < sx2; sx++ )
- {
- assert( k < ssize.width*2 );
- xofs[k].di = dx*cn;
- xofs[k].si = sx*cn;
- xofs[k++].alpha = float(1.0 / min(scale_x, src.cols - fsx1));
- }
+ int xtab_size = computeResizeAreaTab(ssize.width, dsize.width, cn, scale_x, xtab);
+ int ytab_size = computeResizeAreaTab(ssize.height, dsize.height, 1, scale_y, ytab);
- if( fsx2 - sx2 > 1e-3 )
+ AutoBuffer _tabofs(dsize.height + 1);
+ int* tabofs = _tabofs;
+ for( k = 0, dy = 0; k < ytab_size; k++ )
+ {
+ if( k == 0 || ytab[k].di != ytab[k-1].di )
{
- assert( k < ssize.width*2 );
- xofs[k].di = dx*cn;
- xofs[k].si = sx2*cn;
- xofs[k++].alpha = (float)(min(fsx2 - sx2, 1.) / min(scale_x, src.cols - fsx1));
+ assert( ytab[k].di == dy );
+ tabofs[dy++] = k;
}
}
+ tabofs[dy] = ytab_size;
- func( src, dst, xofs, k, scale_y);
+ func( src, dst, xtab, xtab_size, ytab, ytab_size, tabofs );
return;
}
}
diff --git a/modules/java/generator/rst_parser.py b/modules/java/generator/rst_parser.py
index 8920986425..65e66f7f9d 100755
--- a/modules/java/generator/rst_parser.py
+++ b/modules/java/generator/rst_parser.py
@@ -202,8 +202,8 @@ class RstParser(object):
# skip lines if line-skipping mode is activated
if skip_code_lines:
- if not l:
- continue
+ if not l:
+ continue
if l.startswith(" "):
None
else:
@@ -293,19 +293,19 @@ class RstParser(object):
# record other lines as long description
if (skip_code_lines):
- ll = ll.replace("/*", "/ *")
- ll = ll.replace("*/", "* /")
- if (was_code_line):
- func["long"] = func.get("long", "") + "\n" + ll + "\n"
- else:
- was_code_line = True;
- func["long"] = func.get("long", "") + ll +"\n\n\n // C++ code:\n\n"
- else:
- if (was_code_line):
- func["long"] = func.get("long", "") + "\n" + ll + "\n
\n";
- was_code_line = False;
- else:
- func["long"] = func.get("long", "") + "\n" + ll
+ ll = ll.replace("/*", "/ *")
+ ll = ll.replace("*/", "* /")
+ if (was_code_line):
+ func["long"] = func.get("long", "") + "\n" + ll + "\n"
+ else:
+ was_code_line = True;
+ func["long"] = func.get("long", "") + ll +"\n\n\n // C++ code:\n\n"
+ else:
+ if (was_code_line):
+ func["long"] = func.get("long", "") + "\n" + ll + "\n
\n";
+ was_code_line = False;
+ else:
+ func["long"] = func.get("long", "") + "\n" + ll
# endfor l in lines
if fdecl.balance != 0: