Hi,
I want to perform the feature detection from the example app on a jpeg image instead of the camera image. I have the jpeg image stored in a byte array, but how can I convert it to a RGB or YUV image, so that I can work with it with the FastCv SDK? Are there any methods within the API? I have only found methods to convert between RGB and YUV.
In the next step I would need to convert the RGB image (RGB565 in best case) to a grayscale image. How can I do that? In the sample app the YUV image was used and as far as I understood it's easy to extract the grayscale image, since i can just ignore the color part at the end of the image and only use the brightness part at the beginning (with a size of w*h bytes). Is this correct?
Use OpenCV (or your favorite SDK) to load and convert the image. OpenCV code might look something like:
IplImage* img = cvLoadImage( "/sdcard/test.jpg" );
IplImage* src = cvCreateImage( cvSize(img->width,img->height), IPL_DEPTH_8U, 1 );
cvCvtColor( img, src, CV_BGR2GRAY );
IplImage* dst = cvCreateImage( cvSize(img->width,img->height), IPL_DEPTH_8U, 1 );
fcvFilterGaussian5x5u8( src->imageData, img->width, img->height, dst->imageData, 0 );
If you don't mind a little Java code, another way to load the JPG is to use Android's BitmapFactory class. Here is the example Java code, which calls the JNI convertToLum():
/**
* Loads a JPEG into luminance data
* @param fileName
*/
private void loadJPEG( String fileName )
{
Bitmap bmp = BitmapFactory.decodeFile( fileName );
if( bmp != null && bmp.getConfig() == Bitmap.Config.RGB_565 ) {
ShortBuffer rgbBuf =
ShortBuffer.allocate( bmp.getWidth()*bmp.getHeight() );
bmp.copyPixelsToBuffer( rgbBuf );
convertToLum( rgbBuf.array(), bmp.getWidth(), bmp.getHeight() );
}
}
/**
* Performs conversion from RGB565 to Luminance in native.
* @param data ShortByte.array() data.
* @param w Width of buffer
* @param h Height of buffer
*/
private native void convertToLum( short[] data, int w, int h );
The JNI code to convert to Luminance and then be used with FastCV is here:
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
JNIEXPORT void
JNICALL Java_com_qualcomm_loadjpeg_LoadJpeg_convertToLum
(
JNIEnv* env,
jobject obj,
jshortArray img,
jint w,
jint h
)
{
jshort* jimgData = NULL;
jboolean isCopy = 0;
DPRINTF( "%s %d\n", __FILE__, __LINE__ );
if( img != NULL )
{
// Get data from JNI
jimgData = env->GetShortArrayElements( img, &isCopy );
uint8_t* lum = (uint8_t*)fcvMemAlloc( w*h, 16 );
convertRGB565ToY( (uint8_t*)jimgData, w, h, lum );
fcvMemFree( lum );
// Let JNI know we don't need data anymore. this is important!
env->ReleaseShortArrayElements( img, jimgData, JNI_ABORT );
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void convertRGB565ToY( uint8_t* src,
unsigned int srcWidth,
unsigned int srcHeight,
uint8_t* dst )
{
unsigned int size = srcWidth * srcHeight;
uint16_t rgb;
uint16_t r;
uint16_t g;
uint16_t b;
for( unsigned int i=0; i<size; i++ ){
rgb = ((uint16_t*)src)[i];
r = (uint16_t)((rgb&0xF800) >> 8);
g = (uint16_t)((rgb&0x07E0) >> 3);
b = (uint16_t)((rgb&0x001F) << 3);
dst[i] = (uint8_t)(((r<<1) + (g<<2) + g + b)>>3);
}
}
Thanks both of you. I have tried the approach with the BitmapFactory and it worked for me!
HI there
For me ,i usually convert the image using this image converter.It supports to convert image effectively.You can also have a try.Besides,
it offers a free trial package for new users.You can have a try before you decided to own it.I think it would be more convenient if you own a powerful image program.
Hope to help you.