diff --git a/modules/imgproc/include/opencv2/imgproc/types_c.h b/modules/imgproc/include/opencv2/imgproc/types_c.h index 86fa7cc380..ed6e492315 100644 --- a/modules/imgproc/include/opencv2/imgproc/types_c.h +++ b/modules/imgproc/include/opencv2/imgproc/types_c.h @@ -221,10 +221,10 @@ enum CV_YUV2BGR = 84, CV_YUV2RGB = 85, - CV_BayerBG2Gray = 86, - CV_BayerGB2Gray = 87, - CV_BayerRG2Gray = 88, - CV_BayerGR2Gray = 89, + CV_BayerBG2GRAY = 86, + CV_BayerGB2GRAY = 87, + CV_BayerRG2GRAY = 88, + CV_BayerGR2GRAY = 89, CV_COLORCVT_MAX =100 }; diff --git a/modules/imgproc/src/color.cpp b/modules/imgproc/src/color.cpp index 74660a7e29..d8304332c7 100644 --- a/modules/imgproc/src/color.cpp +++ b/modules/imgproc/src/color.cpp @@ -1751,20 +1751,18 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code ) int dst_step = (int)dstmat.step; Size size = srcmat.size(); int bcoeff = B2Y, rcoeff = R2Y; - int start_with_green = code == CV_BayerGB2Gray || code == CV_BayerGR2Gray; - bool brow = false; + 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 ) + if( code != CV_BayerBG2GRAY && code != CV_BayerGB2GRAY ) { - brow = true; + brow = false; std::swap(bcoeff, rcoeff); } - memset( dst0, 0, size.width*sizeof(dst0[0]) ); - memset( dst0 + (size.height - 1)*dst_step, 0, size.width*sizeof(dst0[0]) ); dst0 += dst_step + 1; size.height -= 2; size.width -= 2; @@ -1776,10 +1774,11 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code ) uchar* dst = dst0; const uchar* bayer_end = bayer + size.width; - dst[-1] = dst[size.width+1] = 0; - if( size.width <= 0 ) + { + dst[-1] = dst[size.width] = 0; continue; + } if( start_with_green ) { @@ -1856,10 +1855,27 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code ) dst++; } + dst0[-1] = dst0[0]; + dst0[size.width] = dst0[size.width-1]; + brow = !brow; std::swap(bcoeff, rcoeff); start_with_green = !start_with_green; } + + size = dstmat.size(); + dst0 = dstmat.data; + if( size.height > 2 ) + for( int i = 0; i < size.width; i++ ) + { + dst0[i] = dst0[i + dst_step]; + dst0[i + (size.height-1)*dst_step] = dst0[i + (size.height-2)*dst_step]; + } + else + for( int i = 0; i < size.width; i++ ) + { + dst0[i] = dst0[i + (size.height-1)*dst_step] = 0; + } } @@ -1870,43 +1886,36 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code ) uchar* dst0 = dstmat.data; int dst_step = (int)dstmat.step; Size size = srcmat.size(); + int blue = code == CV_BayerBG2BGR || code == CV_BayerGB2BGR ? -1 : 1; int start_with_green = code == CV_BayerGB2BGR || code == CV_BayerGR2BGR; - bool brow = false; -#if CV_SSE2 +#if CV_SSE2 bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2); -#endif - - if( code != CV_BayerBG2Gray && code != CV_BayerGB2Gray ) - brow = true; +#endif - memset( dst0, 0, size.width*3*sizeof(dst0[0]) ); - memset( dst0 + (size.height - 1)*dst_step, 0, size.width*3*sizeof(dst0[0]) ); - dst0 += dst_step + 4; + dst0 += dst_step + 3 + 1; size.height -= 2; size.width -= 2; - + for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step ) { - int t0, t1, t2; + int t0, t1; const uchar* bayer = bayer0; uchar* dst = dst0; const uchar* bayer_end = bayer + size.width; - int blue = brow ? -1 : 1; - - dst[-4] = dst[-3] = dst[-2] = - dst[size.width*3+3] = dst[size.width*3+4] = dst[size.width*3+5] = 0; if( size.width <= 0 ) + { + dst[-4] = dst[-3] = dst[-2] = dst[size.width*3-1] = + dst[size.width*3] = dst[size.width*3+1] = 0; continue; + } if( start_with_green ) { - t0 = (bayer[1] + bayer[bayer_step*2+1] + 1)>>1; - t1 = (bayer[bayer_step] + bayer[bayer_step+2]+1)>>1; - t2 = bayer[bayer_step+1]; - + 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[0] = (uchar)t2; + dst[0] = bayer[bayer_step+1]; dst[blue] = (uchar)t1; bayer++; dst += 3; @@ -1921,7 +1930,7 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code ) 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(brow ? -1 : 0), z = _mm_setzero_si128(); + __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 ) @@ -1992,43 +2001,84 @@ static void Bayer2RGB_8u( const Mat& srcmat, Mat& dstmat, int code ) } #endif - for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 ) + if( blue > 0 ) { - t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2]+2)>>2; - t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1]+2)>>2; - t2 = bayer[bayer_step+1]; - - dst[-blue] = (uchar)t0; - dst[0] = (uchar)t1; - dst[blue] = (uchar)t2; - - t0 = (bayer[2] + bayer[bayer_step*2+2]+1)>>1; - t1 = (bayer[bayer_step+1] + bayer[bayer_step+3]+1)>>1; - t2 = bayer[bayer_step+2]; - - dst[3-blue] = (uchar)t0; - dst[3] = (uchar)t2; - dst[3+blue] = (uchar)t1; + for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 ) + { + t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + + 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] = 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[3] = bayer[bayer_step+2]; + dst[4] = (uchar)t1; + } + } + else + { + for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 ) + { + t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + + 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] = 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[3] = bayer[bayer_step+2]; + dst[2] = (uchar)t1; + } } if( bayer < bayer_end ) { - t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2] + 2)>>2; - t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1]+2)>>2; - t2 = bayer[bayer_step+1]; - + t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + + 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] = (uchar)t2; + dst[blue] = bayer[bayer_step+1]; bayer++; dst += 3; } - brow = !brow; + dst0[-4] = dst0[-1]; + dst0[-3] = dst0[0]; + dst0[-2] = dst0[1]; + dst0[size.width*3-1] = dst0[size.width*3-4]; + dst0[size.width*3] = dst0[size.width*3-3]; + dst0[size.width*3+1] = dst0[size.width*3-2]; + + blue = -blue; start_with_green = !start_with_green; } -} + size = dstmat.size(); + dst0 = dstmat.data; + if( size.height > 2 ) + for( int i = 0; i < size.width*3; i++ ) + { + dst0[i] = dst0[i + dst_step]; + dst0[i + (size.height-1)*dst_step] = dst0[i + (size.height-2)*dst_step]; + } + else + for( int i = 0; i < size.width*3; i++ ) + { + dst0[i] = dst0[i + (size.height-1)*dst_step] = 0; + } +} + /////////////////// Demosaicing using Variable Number of Gradients /////////////////////// @@ -2853,7 +2903,7 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn ) } break; - case CV_BayerBG2Gray: case CV_BayerGB2Gray: case CV_BayerRG2Gray: case CV_BayerGR2Gray: + 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 ); dst.create(sz, depth); diff --git a/tests/cv/src/acolor.cpp b/tests/cv/src/acolor.cpp index 385f476c09..3608eb59ea 100644 --- a/tests/cv/src/acolor.cpp +++ b/tests/cv/src/acolor.cpp @@ -1734,9 +1734,6 @@ void CV_ColorBayerTest::prepare_to_validation( int /*test_case_idx*/ ) int bi = 0; int step = src->step; - memset( dst->data.ptr, 0, dst->cols*3 ); - memset( dst->data.ptr + (dst->rows-1)*dst->step, 0, dst->cols*3 ); - if( fwd_code == CV_BayerRG2BGR || fwd_code == CV_BayerGR2BGR ) bi ^= 2; @@ -1745,8 +1742,12 @@ void CV_ColorBayerTest::prepare_to_validation( int /*test_case_idx*/ ) const uchar* ptr = src->data.ptr + i*step + 1; uchar* dst_row = dst->data.ptr + i*dst->step + 3; int save_code = code; - dst_row[-3] = dst_row[-2] = dst_row[-1] = 0; - dst_row[cols*3] = dst_row[cols*3+1] = dst_row[cols*3+2] = 0; + if( cols <= 0 ) + { + dst_row[-3] = dst_row[-2] = dst_row[-1] = 0; + dst_row[cols*3] = dst_row[cols*3+1] = dst_row[cols*3+2] = 0; + continue; + } for( j = 0; j < cols; j++ ) { @@ -1768,9 +1769,35 @@ void CV_ColorBayerTest::prepare_to_validation( int /*test_case_idx*/ ) dst_row[j*3 + 1] = (uchar)g; dst_row[j*3 + (bi^2)] = (uchar)r; } + + dst_row[-3] = dst_row[0]; + dst_row[-2] = dst_row[1]; + dst_row[-1] = dst_row[2]; + dst_row[cols*3] = dst_row[cols*3-3]; + dst_row[cols*3+1] = dst_row[cols*3-2]; + dst_row[cols*3+2] = dst_row[cols*3-1]; + code = save_code ^ 1; bi ^= 2; } + + if( src->rows <= 2 ) + { + memset( dst->data.ptr, 0, (cols+2)*3 ); + memset( dst->data.ptr + (dst->rows-1)*dst->step, 0, (cols+2)*3 ); + } + else + { + uchar* top_row = dst->data.ptr; + uchar* bottom_row = dst->data.ptr + dst->step*(dst->rows-1); + int dstep = dst->step; + + for( j = 0; j < (cols+2)*3; j++ ) + { + top_row[j] = top_row[j + dstep]; + bottom_row[j] = bottom_row[j - dstep]; + } + } } CV_ColorBayerTest color_bayer_test;