fixed border processing bayer2rgb & bayer2gray; made the test "color-bayer" pass; renamed CV_Bayer*2Gray -> CV_Bayer*2GRAY for consistency

pull/13383/head
Vadim Pisarevsky 14 years ago
parent d14b744ea9
commit fcdce4edcb
  1. 8
      modules/imgproc/include/opencv2/imgproc/types_c.h
  2. 156
      modules/imgproc/src/color.cpp
  3. 37
      tests/cv/src/acolor.cpp

@ -221,10 +221,10 @@ enum
CV_YUV2BGR = 84, CV_YUV2BGR = 84,
CV_YUV2RGB = 85, CV_YUV2RGB = 85,
CV_BayerBG2Gray = 86, CV_BayerBG2GRAY = 86,
CV_BayerGB2Gray = 87, CV_BayerGB2GRAY = 87,
CV_BayerRG2Gray = 88, CV_BayerRG2GRAY = 88,
CV_BayerGR2Gray = 89, CV_BayerGR2GRAY = 89,
CV_COLORCVT_MAX =100 CV_COLORCVT_MAX =100
}; };

@ -1751,20 +1751,18 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code )
int dst_step = (int)dstmat.step; int dst_step = (int)dstmat.step;
Size size = srcmat.size(); Size size = srcmat.size();
int bcoeff = B2Y, rcoeff = R2Y; int bcoeff = B2Y, rcoeff = R2Y;
int start_with_green = code == CV_BayerGB2Gray || code == CV_BayerGR2Gray; int start_with_green = code == CV_BayerGB2GRAY || code == CV_BayerGR2GRAY;
bool brow = false; bool brow = true;
#if CV_SSE2 #if CV_SSE2
bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2); bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2);
#endif #endif
if( code != CV_BayerBG2Gray && code != CV_BayerGB2Gray ) if( code != CV_BayerBG2GRAY && code != CV_BayerGB2GRAY )
{ {
brow = true; brow = false;
std::swap(bcoeff, rcoeff); 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; dst0 += dst_step + 1;
size.height -= 2; size.height -= 2;
size.width -= 2; size.width -= 2;
@ -1776,10 +1774,11 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code )
uchar* dst = dst0; uchar* dst = dst0;
const uchar* bayer_end = bayer + size.width; const uchar* bayer_end = bayer + size.width;
dst[-1] = dst[size.width+1] = 0;
if( size.width <= 0 ) if( size.width <= 0 )
{
dst[-1] = dst[size.width] = 0;
continue; continue;
}
if( start_with_green ) if( start_with_green )
{ {
@ -1856,10 +1855,27 @@ static void Bayer2Gray_8u( const Mat& srcmat, Mat& dstmat, int code )
dst++; dst++;
} }
dst0[-1] = dst0[0];
dst0[size.width] = dst0[size.width-1];
brow = !brow; brow = !brow;
std::swap(bcoeff, rcoeff); std::swap(bcoeff, rcoeff);
start_with_green = !start_with_green; 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; uchar* dst0 = dstmat.data;
int dst_step = (int)dstmat.step; int dst_step = (int)dstmat.step;
Size size = srcmat.size(); Size size = srcmat.size();
int blue = code == CV_BayerBG2BGR || code == CV_BayerGB2BGR ? -1 : 1;
int start_with_green = code == CV_BayerGB2BGR || code == CV_BayerGR2BGR; 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); bool haveSSE2 = checkHardwareSupport(CV_CPU_SSE2);
#endif #endif
if( code != CV_BayerBG2Gray && code != CV_BayerGB2Gray )
brow = true;
memset( dst0, 0, size.width*3*sizeof(dst0[0]) ); dst0 += dst_step + 3 + 1;
memset( dst0 + (size.height - 1)*dst_step, 0, size.width*3*sizeof(dst0[0]) );
dst0 += dst_step + 4;
size.height -= 2; size.height -= 2;
size.width -= 2; size.width -= 2;
for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step ) for( ; size.height-- > 0; bayer0 += bayer_step, dst0 += dst_step )
{ {
int t0, t1, t2; int t0, t1;
const uchar* bayer = bayer0; const uchar* bayer = bayer0;
uchar* dst = dst0; uchar* dst = dst0;
const uchar* bayer_end = bayer + size.width; 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 ) 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; continue;
}
if( start_with_green ) if( start_with_green )
{ {
t0 = (bayer[1] + bayer[bayer_step*2+1] + 1)>>1; t0 = (bayer[1] + bayer[bayer_step*2+1] + 1) >> 1;
t1 = (bayer[bayer_step] + bayer[bayer_step+2]+1)>>1; t1 = (bayer[bayer_step] + bayer[bayer_step+2] + 1) >> 1;
t2 = bayer[bayer_step+1];
dst[-blue] = (uchar)t0; dst[-blue] = (uchar)t0;
dst[0] = (uchar)t2; dst[0] = bayer[bayer_step+1];
dst[blue] = (uchar)t1; dst[blue] = (uchar)t1;
bayer++; bayer++;
dst += 3; 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 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 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); __m128i masklo = _mm_set1_epi16(0x00ff);
for( ; bayer <= bayer_end - 18; bayer += 14, dst += 42 ) 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 #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; for( ; bayer <= bayer_end - 2; bayer += 2, dst += 6 )
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;
dst[-blue] = (uchar)t0; t1 = (bayer[1] + bayer[bayer_step] +
dst[0] = (uchar)t1; bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2;
dst[blue] = (uchar)t2; dst[-1] = (uchar)t0;
dst[0] = (uchar)t1;
t0 = (bayer[2] + bayer[bayer_step*2+2]+1)>>1; dst[1] = bayer[bayer_step+1];
t1 = (bayer[bayer_step+1] + bayer[bayer_step+3]+1)>>1;
t2 = bayer[bayer_step+2]; t0 = (bayer[2] + bayer[bayer_step*2+2] + 1) >> 1;
t1 = (bayer[bayer_step+1] + bayer[bayer_step+3] + 1) >> 1;
dst[3-blue] = (uchar)t0; dst[2] = (uchar)t0;
dst[3] = (uchar)t2; dst[3] = bayer[bayer_step+2];
dst[3+blue] = (uchar)t1; 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 ) if( bayer < bayer_end )
{ {
t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] + bayer[bayer_step*2+2] + 2)>>2; t0 = (bayer[0] + bayer[2] + bayer[bayer_step*2] +
t1 = (bayer[1] + bayer[bayer_step] + bayer[bayer_step+2] + bayer[bayer_step*2+1]+2)>>2; bayer[bayer_step*2+2] + 2) >> 2;
t2 = bayer[bayer_step+1]; t1 = (bayer[1] + bayer[bayer_step] +
bayer[bayer_step+2] + bayer[bayer_step*2+1]+2) >> 2;
dst[-blue] = (uchar)t0; dst[-blue] = (uchar)t0;
dst[0] = (uchar)t1; dst[0] = (uchar)t1;
dst[blue] = (uchar)t2; dst[blue] = bayer[bayer_step+1];
bayer++; bayer++;
dst += 3; 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; 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 /////////////////////// /////////////////// Demosaicing using Variable Number of Gradients ///////////////////////
@ -2853,7 +2903,7 @@ void cvtColor( const Mat& src, Mat& dst, int code, int dcn )
} }
break; 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; if(dcn <= 0) dcn = 1;
CV_Assert( scn == 1 && dcn == 1 && depth == CV_8U ); CV_Assert( scn == 1 && dcn == 1 && depth == CV_8U );
dst.create(sz, depth); dst.create(sz, depth);

@ -1734,9 +1734,6 @@ void CV_ColorBayerTest::prepare_to_validation( int /*test_case_idx*/ )
int bi = 0; int bi = 0;
int step = src->step; 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 ) if( fwd_code == CV_BayerRG2BGR || fwd_code == CV_BayerGR2BGR )
bi ^= 2; 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; const uchar* ptr = src->data.ptr + i*step + 1;
uchar* dst_row = dst->data.ptr + i*dst->step + 3; uchar* dst_row = dst->data.ptr + i*dst->step + 3;
int save_code = code; int save_code = code;
dst_row[-3] = dst_row[-2] = dst_row[-1] = 0; if( cols <= 0 )
dst_row[cols*3] = dst_row[cols*3+1] = dst_row[cols*3+2] = 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++ ) 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 + 1] = (uchar)g;
dst_row[j*3 + (bi^2)] = (uchar)r; 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; code = save_code ^ 1;
bi ^= 2; 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; CV_ColorBayerTest color_bayer_test;

Loading…
Cancel
Save