From 2e7e754032e41830f591e45217c8db29fcdfdc79 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 14 May 2015 08:06:46 +0300 Subject: [PATCH] added support for n-channel (n>4) images in warpAffine/warpPerspective/remap: http://code.opencv.org/issues/4190 --- modules/imgproc/src/imgwarp.cpp | 26 +++++++++++++++++++------- modules/imgproc/test/test_imgwarp.cpp | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/modules/imgproc/src/imgwarp.cpp b/modules/imgproc/src/imgwarp.cpp index 8a11515..792ba1d 100644 --- a/modules/imgproc/src/imgwarp.cpp +++ b/modules/imgproc/src/imgwarp.cpp @@ -3805,20 +3805,20 @@ static void remapBilinear( const Mat& _src, Mat& _dst, const Mat& _xy, typedef typename CastOp::rtype T; typedef typename CastOp::type1 WT; Size ssize = _src.size(), dsize = _dst.size(); - int cn = _src.channels(); + int k, cn = _src.channels(); const AT* wtab = (const AT*)_wtab; const T* S0 = _src.ptr(); size_t sstep = _src.step/sizeof(S0[0]); - Scalar_ cval(saturate_cast(_borderValue[0]), - saturate_cast(_borderValue[1]), - saturate_cast(_borderValue[2]), - saturate_cast(_borderValue[3])); + T cval[CV_CN_MAX]; int dx, dy; CastOp castOp; VecOp vecOp; + for( k = 0; k < cn; k++ ) + cval[k] = saturate_cast(_borderValue[k & 3]); + unsigned width1 = std::max(ssize.width-1, 0), height1 = std::max(ssize.height-1, 0); - CV_Assert( cn <= 4 && ssize.area() > 0 ); + CV_Assert( ssize.area() > 0 ); #if CV_SSE2 if( _src.type() == CV_8UC3 ) width1 = std::max(ssize.width-2, 0); @@ -3882,7 +3882,7 @@ static void remapBilinear( const Mat& _src, Mat& _dst, const Mat& _xy, WT t2 = S[2]*w[0] + S[5]*w[1] + S[sstep+2]*w[2] + S[sstep+5]*w[3]; D[0] = castOp(t0); D[1] = castOp(t1); D[2] = castOp(t2); } - else + else if( cn == 4 ) for( ; dx < X1; dx++, D += 4 ) { int sx = XY[dx*2], sy = XY[dx*2+1]; @@ -3895,6 +3895,18 @@ static void remapBilinear( const Mat& _src, Mat& _dst, const Mat& _xy, t1 = S[3]*w[0] + S[7]*w[1] + S[sstep+3]*w[2] + S[sstep+7]*w[3]; D[2] = castOp(t0); D[3] = castOp(t1); } + else + for( ; dx < X1; dx++, D += cn ) + { + int sx = XY[dx*2], sy = XY[dx*2+1]; + const AT* w = wtab + FXY[dx]*4; + const T* S = S0 + sy*sstep + sx*cn; + for( k = 0; k < cn; k++ ) + { + WT t0 = S[k]*w[0] + S[k+cn]*w[1] + S[sstep+k]*w[2] + S[sstep+k+cn]*w[3]; + D[k] = castOp(t0); + } + } } else { diff --git a/modules/imgproc/test/test_imgwarp.cpp b/modules/imgproc/test/test_imgwarp.cpp index 176c990..9fa48de 100644 --- a/modules/imgproc/test/test_imgwarp.cpp +++ b/modules/imgproc/test/test_imgwarp.cpp @@ -1632,4 +1632,26 @@ TEST(Resize, Area_half) } } +TEST(Imgproc_Warp, multichannel) +{ + RNG& rng = theRNG(); + for( int iter = 0; iter < 30; iter++ ) + { + int width = rng.uniform(3, 333); + int height = rng.uniform(3, 333); + int cn = rng.uniform(1, 10); + Mat src(height, width, CV_8UC(cn)), dst; + //randu(src, 0, 256); + src.setTo(0.); + + Mat rot = getRotationMatrix2D(Point2f(0.f, 0.f), 1, 1); + warpAffine(src, dst, rot, src.size()); + ASSERT_EQ(0.0, norm(dst, NORM_INF)); + Mat rot2 = Mat::eye(3, 3, rot.type()); + rot.copyTo(rot2.rowRange(0, 2)); + warpPerspective(src, dst, rot2, src.size()); + ASSERT_EQ(0.0, norm(dst, NORM_INF)); + } +} + /* End of file. */ -- 2.7.4