From 2c1e913b2d83543b65bd093c57c559ceea093367 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Fri, 3 Jun 2011 15:45:50 +0000 Subject: [PATCH] added 16-bit support to Bayer2RGB & Bayer2Gray (ticket #686); fixed bug in cv.CreateHist() when no ranges are passed (ticket #990) --- modules/imgproc/src/color.cpp | 392 +++++++++++++++++++++---------------- modules/imgproc/test/test_main.cpp | 35 ---- modules/python/src1/cv.cpp | 8 +- 3 files changed, 231 insertions(+), 204 deletions(-) diff --git a/modules/imgproc/src/color.cpp b/modules/imgproc/src/color.cpp index 6d51b01..bf65a31 100644 --- a/modules/imgproc/src/color.cpp +++ b/modules/imgproc/src/color.cpp @@ -1725,24 +1725,182 @@ struct Luv2RGB_b //////////////////////////// Bayer Pattern -> RGB conversion ///////////////////////////// -static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code ) +template +class SIMDBayerStubInterpolator_ { +public: + int bayer2Gray(const T*, int, T*, int, int, int, int) const + { + return 0; + } + + int bayer2RGB(const T*, int, T*, int, int) const + { + return 0; + } +}; + +#if CV_SSE2 +class SIMDBayerInterpolator_8u +{ +public: + SIMDBayerInterpolator_8u() + { + use_simd = checkHardwareSupport(CV_CPU_SSE2); + } + + int bayer2Gray(const uchar* bayer, int bayer_step, uchar* dst, + int width, int bcoeff, int gcoeff, int rcoeff) const + { + if( !use_simd ) + return 0; + + __m128i _b2y = _mm_set1_epi16((short)(rcoeff*2)); + __m128i _g2y = _mm_set1_epi16((short)(gcoeff*2)); + __m128i _r2y = _mm_set1_epi16((short)(bcoeff*2)); + const uchar* bayer_end = bayer + width; + + for( ; bayer <= bayer_end - 18; bayer += 14, dst += 14 ) + { + __m128i r0 = _mm_loadu_si128((const __m128i*)bayer); + __m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step)); + __m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2)); + + __m128i b1 = _mm_add_epi16(_mm_srli_epi16(_mm_slli_epi16(r0, 8), 8), + _mm_srli_epi16(_mm_slli_epi16(r2, 8), 8)); + __m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2)); + b1 = _mm_slli_epi16(_mm_srli_si128(b1, 2), 1); + + __m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 8), _mm_srli_epi16(r2, 8)); + __m128i g1 = _mm_srli_epi16(_mm_slli_epi16(r1, 8), 8); + g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2))); + g1 = _mm_slli_epi16(_mm_srli_si128(g1, 2), 2); + + r0 = _mm_srli_epi16(r1, 8); + r1 = _mm_slli_epi16(_mm_add_epi16(r0, _mm_srli_si128(r0, 2)), 1); + r0 = _mm_slli_epi16(r0, 2); + + g0 = _mm_add_epi16(_mm_mulhi_epi16(b0, _b2y), _mm_mulhi_epi16(g0, _g2y)); + g1 = _mm_add_epi16(_mm_mulhi_epi16(b1, _b2y), _mm_mulhi_epi16(g1, _g2y)); + g0 = _mm_add_epi16(g0, _mm_mulhi_epi16(r0, _r2y)); + g1 = _mm_add_epi16(g1, _mm_mulhi_epi16(r1, _r2y)); + g0 = _mm_srli_epi16(g0, 1); + g1 = _mm_srli_epi16(g1, 1); + g0 = _mm_packus_epi16(g0, g0); + g1 = _mm_packus_epi16(g1, g1); + g0 = _mm_unpacklo_epi8(g0, g1); + _mm_storeu_si128((__m128i*)dst, g0); + } + + return (int)(bayer - (bayer_end - width)); + } + + int bayer2RGB(const uchar* bayer, int bayer_step, uchar* dst, int width, int blue) const + { + if( !use_simd ) + return 0; + /* + B G B G | B G B G | B G B G | B G B G + G R G R | G R G R | G R G R | G R G R + B G B G | B G B G | B G B G | B G B G + */ + __m128i delta1 = _mm_set1_epi16(1), delta2 = _mm_set1_epi16(2); + __m128i mask = _mm_set1_epi16(blue < 0 ? -1 : 0), z = _mm_setzero_si128(); + __m128i masklo = _mm_set1_epi16(0x00ff); + const uchar* bayer_end = bayer + width; + + for( ; bayer <= bayer_end - 18; bayer += 14, dst += 42 ) + { + __m128i r0 = _mm_loadu_si128((const __m128i*)bayer); + __m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step)); + __m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2)); + + __m128i b1 = _mm_add_epi16(_mm_and_si128(r0, masklo), _mm_and_si128(r2, masklo)); + __m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2)); + b1 = _mm_srli_si128(b1, 2); + b1 = _mm_srli_epi16(_mm_add_epi16(b1, delta1), 1); + b0 = _mm_srli_epi16(_mm_add_epi16(b0, delta2), 2); + b0 = _mm_packus_epi16(b0, b1); + + __m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 8), _mm_srli_epi16(r2, 8)); + __m128i g1 = _mm_and_si128(r1, masklo); + g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2))); + g1 = _mm_srli_si128(g1, 2); + g0 = _mm_srli_epi16(_mm_add_epi16(g0, delta2), 2); + g0 = _mm_packus_epi16(g0, g1); + + r0 = _mm_srli_epi16(r1, 8); + r1 = _mm_add_epi16(r0, _mm_srli_si128(r0, 2)); + r1 = _mm_srli_epi16(_mm_add_epi16(r1, delta1), 1); + r0 = _mm_packus_epi16(r0, r1); + + b1 = _mm_and_si128(_mm_xor_si128(b0, r0), mask); + b0 = _mm_xor_si128(b0, b1); + r0 = _mm_xor_si128(r0, b1); + + // b1 g1 b1 g1 ... + b1 = _mm_unpackhi_epi8(b0, g0); + // b0 g0 b2 g2 b4 g4 .... + b0 = _mm_unpacklo_epi8(b0, g0); + + // r1 0 r3 0 ... + r1 = _mm_unpackhi_epi8(r0, z); + // r0 0 r2 0 r4 0 ... + r0 = _mm_unpacklo_epi8(r0, z); + + // 0 b0 g0 r0 0 b2 g2 r2 0 ... + g0 = _mm_slli_si128(_mm_unpacklo_epi16(b0, r0), 1); + // 0 b8 g8 r8 0 b10 g10 r10 0 ... + g1 = _mm_slli_si128(_mm_unpackhi_epi16(b0, r0), 1); + + // b1 g1 r1 0 b3 g3 r3 .... + r0 = _mm_unpacklo_epi16(b1, r1); + // b9 g9 r9 0 ... + r1 = _mm_unpackhi_epi16(b1, r1); + + b0 = _mm_srli_si128(_mm_unpacklo_epi32(g0, r0), 1); + b1 = _mm_srli_si128(_mm_unpackhi_epi32(g0, r0), 1); + + _mm_storel_epi64((__m128i*)(dst-1+0), b0); + _mm_storel_epi64((__m128i*)(dst-1+6*1), _mm_srli_si128(b0, 8)); + _mm_storel_epi64((__m128i*)(dst-1+6*2), b1); + _mm_storel_epi64((__m128i*)(dst-1+6*3), _mm_srli_si128(b1, 8)); + + g0 = _mm_srli_si128(_mm_unpacklo_epi32(g1, r1), 1); + g1 = _mm_srli_si128(_mm_unpackhi_epi32(g1, r1), 1); + + _mm_storel_epi64((__m128i*)(dst-1+6*4), g0); + _mm_storel_epi64((__m128i*)(dst-1+6*5), _mm_srli_si128(g0, 8)); + + _mm_storel_epi64((__m128i*)(dst-1+6*6), g1); + } + + return (int)(bayer - (bayer_end - width)); + } + + bool use_simd; +}; +#else +typedef SIMDBayerStubInterpolator_ SIMDBayerInterpolator_8u; +#endif + +template +static void Bayer2Gray_( const Mat& srcmat, Mat& dstmat, int code ) +{ + SIMDInterpolator vecOp; const int R2Y = 4899; const int G2Y = 9617; const int B2Y = 1868; const int SHIFT = 14; - const uchar* bayer0 = srcmat.data; - int bayer_step = (int)srcmat.step; - uchar* dst0 = dstmat.data; - int dst_step = (int)dstmat.step; + const T* bayer0 = (const T*)srcmat.data; + int bayer_step = (int)(srcmat.step/sizeof(T)); + T* dst0 = (T*)dstmat.data; + int dst_step = (int)(dstmat.step/sizeof(T)); Size size = srcmat.size(); int bcoeff = B2Y, rcoeff = R2Y; int start_with_green = code == CV_BayerGB2GRAY || code == CV_BayerGR2GRAY; bool brow = true; -#if CV_SSE2 - bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2); -#endif if( code != CV_BayerBG2GRAY && code != CV_BayerGB2GRAY ) { @@ -1756,10 +1914,10 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code ) for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step ) { - int t0, t1, t2; - const uchar* bayer = bayer0; - uchar* dst = dst0; - const uchar* bayer_end = bayer + size.width; + unsigned t0, t1, t2; + const T* bayer = bayer0; + T* dst = dst0; + const T* bayer_end = bayer + size.width; if( size.width <= 0 ) { @@ -1773,63 +1931,26 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code ) t1 = (bayer[bayer_step] + bayer[bayer_step+2])*bcoeff; t2 = bayer[bayer_step+1]*(2*G2Y); - dst[0] = (uchar)CV_DESCALE(t0 + t1 + t2, SHIFT+1); + dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+1); bayer++; dst++; } -#if CV_SSE2 - if( haveSSE2 ) - { - __m128i _b2y = _mm_set1_epi16((short)(rcoeff*2)); - __m128i _g2y = _mm_set1_epi16((short)(G2Y*2)); - __m128i _r2y = _mm_set1_epi16((short)(bcoeff*2)); - - for( ; bayer <= bayer_end - 18; bayer += 14, dst += 14 ) - { - __m128i r0 = _mm_loadu_si128((const __m128i*)bayer); - __m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step)); - __m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2)); - - __m128i b1 = _mm_add_epi16(_mm_srli_epi16(_mm_slli_epi16(r0, 8), 8), - _mm_srli_epi16(_mm_slli_epi16(r2, 8), 8)); - __m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2)); - b1 = _mm_slli_epi16(_mm_srli_si128(b1, 2), 1); - - __m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 8), _mm_srli_epi16(r2, 8)); - __m128i g1 = _mm_srli_epi16(_mm_slli_epi16(r1, 8), 8); - g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2))); - g1 = _mm_slli_epi16(_mm_srli_si128(g1, 2), 2); - - r0 = _mm_srli_epi16(r1, 8); - r1 = _mm_slli_epi16(_mm_add_epi16(r0, _mm_srli_si128(r0, 2)), 1); - r0 = _mm_slli_epi16(r0, 2); - - g0 = _mm_add_epi16(_mm_mulhi_epi16(b0, _b2y), _mm_mulhi_epi16(g0, _g2y)); - g1 = _mm_add_epi16(_mm_mulhi_epi16(b1, _b2y), _mm_mulhi_epi16(g1, _g2y)); - g0 = _mm_add_epi16(g0, _mm_mulhi_epi16(r0, _r2y)); - g1 = _mm_add_epi16(g1, _mm_mulhi_epi16(r1, _r2y)); - g0 = _mm_srli_epi16(g0, 1); - g1 = _mm_srli_epi16(g1, 1); - g0 = _mm_packus_epi16(g0, g0); - g1 = _mm_packus_epi16(g1, g1); - g0 = _mm_unpacklo_epi8(g0, g1); - _mm_storeu_si128((__m128i*)dst, g0); - } - } -#endif + int delta = vecOp.bayer2Gray(bayer, bayer_step, dst, size.width, bcoeff, G2Y, rcoeff); + bayer += delta; + dst += delta; for( ; bayer <= bayer_end - 2; bayer += 2, dst += 2 ) { t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2])*rcoeff; t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1])*G2Y; t2 = bayer[bayer_step+1]*(4*bcoeff); - dst[0] = (uchar)CV_DESCALE(t0 + t1 + t2, SHIFT+2); + dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+2); t0 = (bayer[2] + bayer[bayer_step*2+2])*rcoeff; t1 = (bayer[bayer_step+1] + bayer[bayer_step+3])*bcoeff; t2 = bayer[bayer_step+2]*(2*G2Y); - dst[1] = (uchar)CV_DESCALE(t0 + t1 + t2, SHIFT+1); + dst[1] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+1); } if( bayer < bayer_end ) @@ -1837,7 +1958,7 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code ) t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2])*rcoeff; t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1])*G2Y; t2 = bayer[bayer_step+1]*(4*bcoeff); - dst[0] = (uchar)CV_DESCALE(t0 + t1 + t2, SHIFT+2); + dst[0] = (T)CV_DESCALE(t0 + t1 + t2, SHIFT+2); bayer++; dst++; } @@ -1851,7 +1972,7 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code ) } size = dstmat.size(); - dst0 = dstmat.data; + dst0 = (T*)dstmat.data; if( size.height > 2 ) for( int i = 0; i < size.width; i++ ) { @@ -1865,19 +1986,17 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code ) } } - -static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code ) +template +static void Bayer2RGB_( const Mat& srcmat, Mat& dstmat, int code ) { - const uchar* bayer0 = srcmat.data; - int bayer_step = (int)srcmat.step; - uchar* dst0 = dstmat.data; - int dst_step = (int)dstmat.step; + SIMDInterpolator vecOp; + const T* bayer0 = (const T*)srcmat.data; + int bayer_step = (int)(srcmat.step/sizeof(T)); + T* dst0 = (T*)dstmat.data; + int dst_step = (int)(dstmat.step/sizeof(T)); Size size = srcmat.size(); int blue = code == CV_BayerBG2BGR || code == CV_BayerGB2BGR ? -1 : 1; int start_with_green = code == CV_BayerGB2BGR || code == CV_BayerGR2BGR; -#if CV_SSE2 - bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2); -#endif dst0 += dst_step + 3 + 1; size.height -= 2; @@ -1886,9 +2005,9 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code ) for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step ) { int t0, t1; - const uchar* bayer = bayer0; - uchar* dst = dst0; - const uchar* bayer_end = bayer + size.width; + const T* bayer = bayer0; + T* dst = dst0; + const T* bayer_end = bayer + size.width; if( size.width <= 0 ) { @@ -1901,93 +2020,17 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code ) { t0 = (bayer[1] + bayer[bayer_step*2+1] + 1) >> 1; t1 = (bayer[bayer_step] + bayer[bayer_step+2] + 1) >> 1; - dst[-blue] = (uchar)t0; + dst[-blue] = (T)t0; dst[0] = bayer[bayer_step+1]; - dst[blue] = (uchar)t1; + dst[blue] = (T)t1; bayer++; dst += 3; } -#if CV_SSE2 - if( haveSSE2 ) - { - /* - B G B G | B G B G | B G B G | B G B G - G R G R | G R G R | G R G R | G R G R - B G B G | B G B G | B G B G | B G B G - */ - __m128i delta1 = _mm_set1_epi16(1), delta2 = _mm_set1_epi16(2); - __m128i mask = _mm_set1_epi16(blue < 0 ? -1 : 0), z = _mm_setzero_si128(); - __m128i masklo = _mm_set1_epi16(0x00ff); - - for( ; bayer <= bayer_end - 18; bayer += 14, dst += 42 ) - { - __m128i r0 = _mm_loadu_si128((const __m128i*)bayer); - __m128i r1 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step)); - __m128i r2 = _mm_loadu_si128((const __m128i*)(bayer+bayer_step*2)); - - __m128i b1 = _mm_add_epi16(_mm_and_si128(r0, masklo), _mm_and_si128(r2, masklo)); - __m128i b0 = _mm_add_epi16(b1, _mm_srli_si128(b1, 2)); - b1 = _mm_srli_si128(b1, 2); - b1 = _mm_srli_epi16(_mm_add_epi16(b1, delta1), 1); - b0 = _mm_srli_epi16(_mm_add_epi16(b0, delta2), 2); - b0 = _mm_packus_epi16(b0, b1); - - __m128i g0 = _mm_add_epi16(_mm_srli_epi16(r0, 8), _mm_srli_epi16(r2, 8)); - __m128i g1 = _mm_and_si128(r1, masklo); - g0 = _mm_add_epi16(g0, _mm_add_epi16(g1, _mm_srli_si128(g1, 2))); - g1 = _mm_srli_si128(g1, 2); - g0 = _mm_srli_epi16(_mm_add_epi16(g0, delta2), 2); - g0 = _mm_packus_epi16(g0, g1); - - r0 = _mm_srli_epi16(r1, 8); - r1 = _mm_add_epi16(r0, _mm_srli_si128(r0, 2)); - r1 = _mm_srli_epi16(_mm_add_epi16(r1, delta1), 1); - r0 = _mm_packus_epi16(r0, r1); - - b1 = _mm_and_si128(_mm_xor_si128(b0, r0), mask); - b0 = _mm_xor_si128(b0, b1); - r0 = _mm_xor_si128(r0, b1); - - // b1 g1 b1 g1 ... - b1 = _mm_unpackhi_epi8(b0, g0); - // b0 g0 b2 g2 b4 g4 .... - b0 = _mm_unpacklo_epi8(b0, g0); - - // r1 0 r3 0 ... - r1 = _mm_unpackhi_epi8(r0, z); - // r0 0 r2 0 r4 0 ... - r0 = _mm_unpacklo_epi8(r0, z); - - // 0 b0 g0 r0 0 b2 g2 r2 0 ... - g0 = _mm_slli_si128(_mm_unpacklo_epi16(b0, r0), 1); - // 0 b8 g8 r8 0 b10 g10 r10 0 ... - g1 = _mm_slli_si128(_mm_unpackhi_epi16(b0, r0), 1); - - // b1 g1 r1 0 b3 g3 r3 .... - r0 = _mm_unpacklo_epi16(b1, r1); - // b9 g9 r9 0 ... - r1 = _mm_unpackhi_epi16(b1, r1); - - b0 = _mm_srli_si128(_mm_unpacklo_epi32(g0, r0), 1); - b1 = _mm_srli_si128(_mm_unpackhi_epi32(g0, r0), 1); + int delta = vecOp.bayer2RGB(bayer, bayer_step, dst, size.width, blue); + bayer += delta; + dst += delta*3; - _mm_storel_epi64((__m128i*)(dst-1+0), b0); - _mm_storel_epi64((__m128i*)(dst-1+6*1), _mm_srli_si128(b0, 8)); - _mm_storel_epi64((__m128i*)(dst-1+6*2), b1); - _mm_storel_epi64((__m128i*)(dst-1+6*3), _mm_srli_si128(b1, 8)); - - g0 = _mm_srli_si128(_mm_unpacklo_epi32(g1, r1), 1); - g1 = _mm_srli_si128(_mm_unpackhi_epi32(g1, r1), 1); - - _mm_storel_epi64((__m128i*)(dst-1+6*4), g0); - _mm_storel_epi64((__m128i*)(dst-1+6*5), _mm_srli_si128(g0, 8)); - - _mm_storel_epi64((__m128i*)(dst-1+6*6), g1); - } - } -#endif - if( blue > 0 ) { for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 ) @@ -1996,15 +2039,15 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code ) bayer[bayer_step*2+2] + 2) >> 2; t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2; - dst[-1] = (uchar)t0; - dst[0] = (uchar)t1; + dst[-1] = (T)t0; + dst[0] = (T)t1; dst[1] = bayer[bayer_step+1]; t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1; t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1; - dst[2] = (uchar)t0; + dst[2] = (T)t0; dst[3] = bayer[bayer_step+2]; - dst[4] = (uchar)t1; + dst[4] = (T)t1; } } else @@ -2015,15 +2058,15 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code ) bayer[bayer_step*2+2] + 2) >> 2; t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2; - dst[1] = (uchar)t0; - dst[0] = (uchar)t1; + dst[1] = (T)t0; + dst[0] = (T)t1; dst[-1] = bayer[bayer_step+1]; t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1; t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1; - dst[4] = (uchar)t0; + dst[4] = (T)t0; dst[3] = bayer[bayer_step+2]; - dst[2] = (uchar)t1; + dst[2] = (T)t1; } } @@ -2033,8 +2076,8 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code ) bayer[bayer_step*2+2] + 2) >> 2; t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2; - dst[-blue] = (uchar)t0; - dst[0] = (uchar)t1; + dst[-blue] = (T)t0; + dst[0] = (T)t1; dst[blue] = bayer[bayer_step+1]; bayer++; dst += 3; @@ -2052,7 +2095,7 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code ) } size = dstmat.size(); - dst0 = dstmat.data; + dst0 = (T*)dstmat.data; if( size.height > 2 ) for( int i = 0; i < size.width*3; i++ ) { @@ -2083,7 +2126,7 @@ static void Bayer2RGB_VNG_8u( const Mat& srcmat, Mat& dstmat, int code ) // for too small images use the simple interpolation algorithm if( MIN(size.width, size.height) < 8 ) { - Bayer2RGB_8u( srcmat, dstmat, code ); + Bayer2RGB_( srcmat, dstmat, code ); return; } @@ -2912,27 +2955,42 @@ void cv::cvtColor( const InputArray& _src, OutputArray _dst, int code, int dcn ) case CV_BayerBG2GRAY: case CV_BayerGB2GRAY: case CV_BayerRG2GRAY: case CV_BayerGR2GRAY: if(dcn <= 0) dcn = 1; - CV_Assert( scn == 1 && dcn == 1 && depth == CV_8U ); + CV_Assert( scn == 1 && dcn == 1 ); _dst.create(sz, depth); dst = _dst.getMat(); - Bayer2Gray_8u(src, dst, code); - break; + if( depth == CV_8U ) + Bayer2Gray_(src, dst, code); + else if( depth == CV_16U ) + Bayer2Gray_ >(src, dst, code); + else + CV_Error(CV_StsUnsupportedFormat, "Bayer->Gray demosaicing only supports 8u and 16u types"); + break; case CV_BayerBG2BGR: case CV_BayerGB2BGR: case CV_BayerRG2BGR: case CV_BayerGR2BGR: case CV_BayerBG2BGR_VNG: case CV_BayerGB2BGR_VNG: case CV_BayerRG2BGR_VNG: case CV_BayerGR2BGR_VNG: if(dcn <= 0) dcn = 3; - CV_Assert( scn == 1 && dcn == 3 && depth == CV_8U ); + CV_Assert( scn == 1 && dcn == 3 ); _dst.create(sz, CV_MAKETYPE(depth, dcn)); dst = _dst.getMat(); if( code == CV_BayerBG2BGR || code == CV_BayerGB2BGR || code == CV_BayerRG2BGR || code == CV_BayerGR2BGR ) - Bayer2RGB_8u(src, dst, code); + { + if( depth == CV_8U ) + Bayer2RGB_(src, dst, code); + else if( depth == CV_16U ) + Bayer2RGB_ >(src, dst, code); + else + CV_Error(CV_StsUnsupportedFormat, "Bayer->RGB demosaicing only supports 8u and 16u types"); + } else + { + CV_Assert( depth == CV_8U ); Bayer2RGB_VNG_8u(src, dst, code); + } break; default: CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); diff --git a/modules/imgproc/test/test_main.cpp b/modules/imgproc/test/test_main.cpp index 15fd135..6b24993 100644 --- a/modules/imgproc/test/test_main.cpp +++ b/modules/imgproc/test/test_main.cpp @@ -1,38 +1,3 @@ #include "test_precomp.hpp" CV_TEST_MAIN("cv") - -#if 0 -using namespace cv; -using namespace std; - -int main(int, char**) -{ -#if 0 - Mat src = imread("/Users/vp/Downloads/resize/original.png"), dst; - //resize(src, dst, Size(), 0.25, 0.25, INTER_NEAREST); - //imwrite("/Users/vp/Downloads/resize/xnview_nn_opencv.png", dst); - printf("\n\n\n\n\n\n***************************************\n"); - //resize(src, dst, Size(), 0.25, 0.25, INTER_AREA); - //int nsteps = 4; - //double rate = pow(0.25,1./nsteps); - //for( int i = 0; i < nsteps; i++ ) - // resize(src, src, Size(), rate, rate, INTER_LINEAR ); - //GaussianBlur(src, src, Size(5, 5), 2, 2); - resize(src, src, Size(), 0.25, 0.25, INTER_NEAREST); - imwrite("/Users/vp/Downloads/resize/xnview_bilinear_opencv.png", src); - //resize(src, dst, Size(), 0.25, 0.25, INTER_LANCZOS4); - //imwrite("/Users/vp/Downloads/resize/xnview_lanczos3_opencv.png", dst); -#else - float data[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24}; - Mat src(5,5,CV_32FC1, data); - Mat dst; - resize(src, dst, Size(), 3, 3, INTER_NEAREST); - cout << src << endl; - cout << dst << endl; -#endif - return 0; -} -#endif - - diff --git a/modules/python/src1/cv.cpp b/modules/python/src1/cv.cpp index 7a65891..283a43f 100644 --- a/modules/python/src1/cv.cpp +++ b/modules/python/src1/cv.cpp @@ -2965,16 +2965,20 @@ static PyObject *pycvCreateHist(PyObject *self, PyObject *args, PyObject *kw) } cvhistogram_t *h = PyObject_NEW(cvhistogram_t, &cvhistogram_Type); args = Py_BuildValue("Oi", dims, CV_32FC1); + memset(&h->h, 0, sizeof(h->h)); h->bins = pycvCreateMatND(self, args); Py_DECREF(args); if (h->bins == NULL) { return NULL; } - h->h.type = CV_HIST_MAGIC_VAL; + h->h.type = CV_HIST_MAGIC_VAL + CV_HIST_UNIFORM_FLAG; if (!convert_to_CvArr(h->bins, &(h->h.bins), "bins")) return NULL; - ERRWRAP(cvSetHistBinRanges(&(h->h), r.rr, uniform)); + if(r.rr) + { + ERRWRAP(cvSetHistBinRanges(&(h->h), r.rr, uniform)); + } return (PyObject*)h; } -- 2.7.4