@ -1321,262 +1321,6 @@ yuv411p_to_rgb24(int width, int height,
}
}
/*
* BAYER2RGB24 ROUTINE TAKEN FROM :
*
* Sonix SN9C10x based webcam basic I / F routines
* Takafumi Mizuno < taka - qce @ ls - a . jp >
*
*/
static void bayer2rgb24 ( long int WIDTH , long int HEIGHT , unsigned char * src , unsigned char * dst )
{
long int i ;
unsigned char * rawpt , * scanpt ;
long int size ;
rawpt = src ;
scanpt = dst ;
size = WIDTH * HEIGHT ;
for ( i = 0 ; i < size ; i + + ) {
if ( ( i / WIDTH ) % 2 = = 0 ) {
if ( ( i % 2 ) = = 0 ) {
/* B */
if ( ( i > WIDTH ) & & ( ( i % WIDTH ) > 0 ) ) {
* scanpt + + = ( * ( rawpt - WIDTH - 1 ) + * ( rawpt - WIDTH + 1 ) +
* ( rawpt + WIDTH - 1 ) + * ( rawpt + WIDTH + 1 ) ) / 4 ; /* R */
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + 1 ) +
* ( rawpt + WIDTH ) + * ( rawpt - WIDTH ) ) / 4 ; /* G */
* scanpt + + = * rawpt ; /* B */
} else {
/* first line or left column */
* scanpt + + = * ( rawpt + WIDTH + 1 ) ; /* R */
* scanpt + + = ( * ( rawpt + 1 ) + * ( rawpt + WIDTH ) ) / 2 ; /* G */
* scanpt + + = * rawpt ; /* B */
}
} else {
/* (B)G */
if ( ( i > WIDTH ) & & ( ( i % WIDTH ) < ( WIDTH - 1 ) ) ) {
* scanpt + + = ( * ( rawpt + WIDTH ) + * ( rawpt - WIDTH ) ) / 2 ; /* R */
* scanpt + + = * rawpt ; /* G */
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + 1 ) ) / 2 ; /* B */
} else {
/* first line or right column */
* scanpt + + = * ( rawpt + WIDTH ) ; /* R */
* scanpt + + = * rawpt ; /* G */
* scanpt + + = * ( rawpt - 1 ) ; /* B */
}
}
} else {
if ( ( i % 2 ) = = 0 ) {
/* G(R) */
if ( ( i < ( WIDTH * ( HEIGHT - 1 ) ) ) & & ( ( i % WIDTH ) > 0 ) ) {
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + 1 ) ) / 2 ; /* R */
* scanpt + + = * rawpt ; /* G */
* scanpt + + = ( * ( rawpt + WIDTH ) + * ( rawpt - WIDTH ) ) / 2 ; /* B */
} else {
/* bottom line or left column */
* scanpt + + = * ( rawpt + 1 ) ; /* R */
* scanpt + + = * rawpt ; /* G */
* scanpt + + = * ( rawpt - WIDTH ) ; /* B */
}
} else {
/* R */
if ( i < ( WIDTH * ( HEIGHT - 1 ) ) & & ( ( i % WIDTH ) < ( WIDTH - 1 ) ) ) {
* scanpt + + = * rawpt ; /* R */
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + 1 ) +
* ( rawpt - WIDTH ) + * ( rawpt + WIDTH ) ) / 4 ; /* G */
* scanpt + + = ( * ( rawpt - WIDTH - 1 ) + * ( rawpt - WIDTH + 1 ) +
* ( rawpt + WIDTH - 1 ) + * ( rawpt + WIDTH + 1 ) ) / 4 ; /* B */
} else {
/* bottom line or right column */
* scanpt + + = * rawpt ; /* R */
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt - WIDTH ) ) / 2 ; /* G */
* scanpt + + = * ( rawpt - WIDTH - 1 ) ; /* B */
}
}
}
rawpt + + ;
}
}
// SGBRG to RGB24
// for some reason, red and blue needs to be swapped
// at least for 046d:092f Logitech, Inc. QuickCam Express Plus to work
//see: http://www.siliconimaging.com/RGB%20Bayer.htm
//and 4.6 at http://tldp.org/HOWTO/html_single/libdc1394-HOWTO/
static void sgbrg2rgb24 ( long int WIDTH , long int HEIGHT , unsigned char * src , unsigned char * dst )
{
long int i ;
unsigned char * rawpt , * scanpt ;
long int size ;
rawpt = src ;
scanpt = dst ;
size = WIDTH * HEIGHT ;
for ( i = 0 ; i < size ; i + + )
{
if ( ( i / WIDTH ) % 2 = = 0 ) //even row
{
if ( ( i % 2 ) = = 0 ) //even pixel
{
if ( ( i > WIDTH ) & & ( ( i % WIDTH ) > 0 ) )
{
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + 1 ) ) / 2 ; /* R */
* scanpt + + = * ( rawpt ) ; /* G */
* scanpt + + = ( * ( rawpt - WIDTH ) + * ( rawpt + WIDTH ) ) / 2 ; /* B */
} else
{
/* first line or left column */
* scanpt + + = * ( rawpt + 1 ) ; /* R */
* scanpt + + = * ( rawpt ) ; /* G */
* scanpt + + = * ( rawpt + WIDTH ) ; /* B */
}
} else //odd pixel
{
if ( ( i > WIDTH ) & & ( ( i % WIDTH ) < ( WIDTH - 1 ) ) )
{
* scanpt + + = * ( rawpt ) ; /* R */
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + 1 ) + * ( rawpt - WIDTH ) + * ( rawpt + WIDTH ) ) / 4 ; /* G */
* scanpt + + = ( * ( rawpt - WIDTH - 1 ) + * ( rawpt - WIDTH + 1 ) + * ( rawpt + WIDTH - 1 ) + * ( rawpt + WIDTH + 1 ) ) / 4 ; /* B */
} else
{
/* first line or right column */
* scanpt + + = * ( rawpt ) ; /* R */
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + WIDTH ) ) / 2 ; /* G */
* scanpt + + = * ( rawpt + WIDTH - 1 ) ; /* B */
}
}
} else
{ //odd row
if ( ( i % 2 ) = = 0 ) //even pixel
{
if ( ( i < ( WIDTH * ( HEIGHT - 1 ) ) ) & & ( ( i % WIDTH ) > 0 ) )
{
* scanpt + + = ( * ( rawpt - WIDTH - 1 ) + * ( rawpt - WIDTH + 1 ) + * ( rawpt + WIDTH - 1 ) + * ( rawpt + WIDTH + 1 ) ) / 4 ; /* R */
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + 1 ) + * ( rawpt - WIDTH ) + * ( rawpt + WIDTH ) ) / 4 ; /* G */
* scanpt + + = * ( rawpt ) ; /* B */
} else
{
/* bottom line or left column */
* scanpt + + = * ( rawpt - WIDTH + 1 ) ; /* R */
* scanpt + + = ( * ( rawpt + 1 ) + * ( rawpt - WIDTH ) ) / 2 ; /* G */
* scanpt + + = * ( rawpt ) ; /* B */
}
} else
{ //odd pixel
if ( i < ( WIDTH * ( HEIGHT - 1 ) ) & & ( ( i % WIDTH ) < ( WIDTH - 1 ) ) )
{
* scanpt + + = ( * ( rawpt - WIDTH ) + * ( rawpt + WIDTH ) ) / 2 ; /* R */
* scanpt + + = * ( rawpt ) ; /* G */
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + 1 ) ) / 2 ; /* B */
} else
{
/* bottom line or right column */
* scanpt + + = ( * ( rawpt - WIDTH ) ) ; /* R */
* scanpt + + = * ( rawpt ) ; /* G */
* scanpt + + = ( * ( rawpt - 1 ) ) ; /* B */
}
}
}
rawpt + + ;
}
}
// SGRBG to RGB24
static void sgrbg2rgb24 ( long int WIDTH , long int HEIGHT , unsigned char * src , unsigned char * dst )
{
long int i ;
unsigned char * rawpt , * scanpt ;
long int size ;
rawpt = src ;
scanpt = dst ;
size = WIDTH * HEIGHT ;
for ( i = 0 ; i < size ; i + + )
{
if ( ( i / WIDTH ) % 2 = = 0 ) //even row
{
if ( ( i % 2 ) = = 0 ) //even pixel
{
if ( ( i > WIDTH ) & & ( ( i % WIDTH ) > 0 ) )
{
* scanpt + + = ( * ( rawpt - WIDTH ) + * ( rawpt + WIDTH ) ) / 2 ; /* R */
* scanpt + + = * ( rawpt ) ; /* G */
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + 1 ) ) / 2 ; /* B */
} else
{
/* first line or left column */
* scanpt + + = * ( rawpt + WIDTH ) ; /* R */
* scanpt + + = * ( rawpt ) ; /* G */
* scanpt + + = * ( rawpt + 1 ) ; /* B */
}
} else //odd pixel
{
if ( ( i > WIDTH ) & & ( ( i % WIDTH ) < ( WIDTH - 1 ) ) )
{
* scanpt + + = ( * ( rawpt - WIDTH - 1 ) + * ( rawpt - WIDTH + 1 ) +
* ( rawpt + WIDTH - 1 ) + * ( rawpt + WIDTH + 1 ) ) / 4 ; /* R */
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + 1 ) +
* ( rawpt - WIDTH ) + * ( rawpt + WIDTH ) ) / 4 ; /* G */
* scanpt + + = * ( rawpt ) ; /* B */
} else
{
/* first line or right column */
* scanpt + + = * ( rawpt + WIDTH - 1 ) ; /* R */
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + WIDTH ) ) / 2 ; /* G */
* scanpt + + = * ( rawpt ) ; /* B */
}
}
} else
{ //odd row
if ( ( i % 2 ) = = 0 ) //even pixel
{
if ( ( i < ( WIDTH * ( HEIGHT - 1 ) ) ) & & ( ( i % WIDTH ) > 0 ) )
{
* scanpt + + = * ( rawpt ) ; /* R */
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + 1 ) +
* ( rawpt - WIDTH ) + * ( rawpt + WIDTH ) ) / 4 ; /* G */
* scanpt + + = ( * ( rawpt - WIDTH - 1 ) + * ( rawpt - WIDTH + 1 ) +
* ( rawpt + WIDTH - 1 ) + * ( rawpt + WIDTH + 1 ) ) / 4 ; /* B */
} else
{
/* bottom line or left column */
* scanpt + + = * ( rawpt ) ; /* R */
* scanpt + + = ( * ( rawpt + 1 ) + * ( rawpt - WIDTH ) ) / 2 ; /* G */
* scanpt + + = * ( rawpt - WIDTH + 1 ) ; /* B */
}
} else
{ //odd pixel
if ( i < ( WIDTH * ( HEIGHT - 1 ) ) & & ( ( i % WIDTH ) < ( WIDTH - 1 ) ) )
{
* scanpt + + = ( * ( rawpt - 1 ) + * ( rawpt + 1 ) ) / 2 ; /* R */
* scanpt + + = * ( rawpt ) ; /* G */
* scanpt + + = ( * ( rawpt - WIDTH ) + * ( rawpt + WIDTH ) ) / 2 ; /* B */
} else
{
/* bottom line or right column */
* scanpt + + = ( * ( rawpt - 1 ) ) ; /* R */
* scanpt + + = * ( rawpt ) ; /* G */
* scanpt + + = ( * ( rawpt - WIDTH ) ) ; /* B */
}
}
}
rawpt + + ;
}
}
# define CLAMP(x) ((x)<0?0:((x)>255)?255:(x))
typedef struct {
@ -1778,28 +1522,6 @@ void CvCaptureCAM_V4L::convertToRgb(const Buffer ¤tBuffer)
yuv411p_to_rgb24 ( imageSize . width , imageSize . height ,
start , ( unsigned char * ) frame . imageData ) ;
return ;
case V4L2_PIX_FMT_SBGGR8 :
bayer2rgb24 ( imageSize . width , imageSize . height ,
start , ( unsigned char * ) frame . imageData ) ;
return ;
case V4L2_PIX_FMT_SN9C10X :
sonix_decompress_init ( ) ;
sonix_decompress ( imageSize . width , imageSize . height ,
start , ( unsigned char * ) buffers [ MAX_V4L_BUFFERS ] . memories [ MEMORY_RGB ] . start ) ;
bayer2rgb24 ( imageSize . width , imageSize . height ,
( unsigned char * ) buffers [ MAX_V4L_BUFFERS ] . memories [ MEMORY_RGB ] . start ,
( unsigned char * ) frame . imageData ) ;
return ;
case V4L2_PIX_FMT_SGBRG8 :
sgbrg2rgb24 ( imageSize . width , imageSize . height ,
start , ( unsigned char * ) frame . imageData ) ;
return ;
case V4L2_PIX_FMT_SGRBG8 :
sgrbg2rgb24 ( imageSize . width , imageSize . height ,
start , ( unsigned char * ) frame . imageData ) ;
return ;
default :
break ;
}
@ -1872,6 +1594,36 @@ void CvCaptureCAM_V4L::convertToRgb(const Buffer ¤tBuffer)
cv : : cvtColor ( temp , destination , COLOR_GRAY2BGR ) ;
return ;
}
case V4L2_PIX_FMT_SN9C10X :
{
sonix_decompress_init ( ) ;
sonix_decompress ( imageSize . width , imageSize . height ,
start , ( unsigned char * ) buffers [ MAX_V4L_BUFFERS ] . memories [ MEMORY_RGB ] . start ) ;
cv : : Mat cv_buf ( imageSize , CV_8UC1 , buffers [ MAX_V4L_BUFFERS ] . memories [ MEMORY_RGB ] . start ) ;
cv : : cvtColor ( cv_buf , destination , COLOR_BayerRG2BGR ) ;
return ;
}
case V4L2_PIX_FMT_SRGGB8 :
{
cv : : cvtColor ( cv : : Mat ( imageSize , CV_8UC1 , start ) , destination , COLOR_BayerBG2BGR ) ;
return ;
}
case V4L2_PIX_FMT_SBGGR8 :
{
cv : : cvtColor ( cv : : Mat ( imageSize , CV_8UC1 , start ) , destination , COLOR_BayerRG2BGR ) ;
return ;
}
case V4L2_PIX_FMT_SGBRG8 :
{
cv : : cvtColor ( cv : : Mat ( imageSize , CV_8UC1 , start ) , destination , COLOR_BayerGR2BGR ) ;
return ;
}
case V4L2_PIX_FMT_SGRBG8 :
{
cv : : cvtColor ( cv : : Mat ( imageSize , CV_8UC1 , start ) , destination , COLOR_BayerGB2BGR ) ;
return ;
}
case V4L2_PIX_FMT_GREY :
cv : : cvtColor ( cv : : Mat ( imageSize , CV_8UC1 , start ) , destination , COLOR_GRAY2BGR ) ;
break ;