diff options
Diffstat (limited to 'sample/src/main.c')
-rwxr-xr-x | sample/src/main.c | 557 |
1 files changed, 557 insertions, 0 deletions
diff --git a/sample/src/main.c b/sample/src/main.c new file mode 100755 index 0000000..8e55f69 --- /dev/null +++ b/sample/src/main.c @@ -0,0 +1,557 @@ +#include <stdio.h> +#include <getopt.h> +#include <jpeglib.h> +#include <stdlib.h> +#include <string.h> + +#include "face.h" + + +#define CIF_W (352) +#define CIF_H (288) + +#define QCIF_W (176) +#define QCIF_H (144) + + +static char *filename = NULL; +static bool bSaveRaw = false; +static bool bVideo = false; + +static void print_usage(char *name, FILE *stream, int exit_code) +{ + fprintf(stream, "Usage : %s [ ... ]\n", name); + fprintf(stream, + " -f --file File name\n" + " -t --type [image,video]\n" + " -v --verbose Print verbose message.\n" + " -s --saveraw Save Y data into file\n" + ); + + exit(exit_code); +} + + +int parse_param(int argc, char *argv[]) +{ + int c; + + if ( argc == 1 ) + { + print_usage(argv[0], stdout, 0); + return 0; + } + + + while (1) + { + static struct option long_options[] = + { + /* These options set a flag. */ +// {"verbose", no_argument, &verbose_flag, 1}, +// {"brief", no_argument, &verbose_flag, 0}, + + /* These options don't set a flag. We distinguish them by their indices. */ + {"file", required_argument, NULL, 0}, + {"type", required_argument, NULL, 0}, + {"saveraw", no_argument, NULL, 0}, + {0, 0, 0, 0} + }; + + /* getopt_long stores the option index here. */ + int option_index = 0; +/* + : ºÙÀ¸¸é ²À ÇÊ¿äÇÑ ¿É¼ÇÀÓÀ» ³ªÅ¸³¿. +*/ + c = getopt_long(argc, argv, "f:t:s", long_options, &option_index); + + /* Detect the end of the options. */ + if (c == -1) + break; + + switch (c) + { + case 0: + /* If this option set a flag, do nothing else now. */ + if (long_options[option_index].flag != 0) break; + + printf ("option %s", long_options[option_index].name); + + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case 'f': + printf ("option -f with value `%s'\n", optarg); + filename = strdup(optarg); + break; + + case 's': + printf ("option -s\n"); + bSaveRaw = true; + break; + + case 't': + printf ("option -t with value `%s'\n", optarg); + + if ( strcmp("video", optarg ) == 0 ) + { + bVideo = true; + } + else + { + bVideo = false; + } + + break; + + case '?': + print_usage(argv[0], stdout, 0); + break; + + default: + abort (); + } + } + + return 0; +} + + + +#if 0 +static void parse_error(int err) +{ + switch(err) + { + case IMAGE_UTIL_ERROR_NONE: + printf("Error=%s\n", "IMAGE_UTIL_ERROR_NONE"); + break; + case IMAGE_UTIL_ERROR_INVALID_PARAMETER: + printf("Error=%s\n", "IMAGE_UTIL_ERROR_INVALID_PARAMETER"); + break; + case IMAGE_UTIL_ERROR_OUT_OF_MEMORY: + printf("Error=%s\n", "IMAGE_UTIL_ERROR_OUT_OF_MEMORY"); + break; + case IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT: + printf("Error=%s\n", "IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT"); + break; + case IMAGE_UTIL_ERROR_INVALID_OPERATION: + printf("Error=%s\n", "IMAGE_UTIL_ERROR_INVALID_OPERATION"); + break; + default: + printf("Unknown Error=%d\n", err); + break; + } + +} + + +static bool _supported_jpeg_colorspace_cb(image_util_colorspace_e colorspace, void *user_data) +{ + struct colorspace { + int color; + char *name; + }; +#define stringify( name ) # name + + struct colorspace list[] = { + { IMAGE_UTIL_COLORSPACE_YUV422, stringify(IMAGE_UTIL_COLORSPACE_YUV422), }, + { IMAGE_UTIL_COLORSPACE_I420, stringify(IMAGE_UTIL_COLORSPACE_I420), }, + { IMAGE_UTIL_COLORSPACE_NV12, stringify(IMAGE_UTIL_COLORSPACE_NV12), }, + { IMAGE_UTIL_COLORSPACE_UYVY, stringify(IMAGE_UTIL_COLORSPACE_UYVY), }, + { IMAGE_UTIL_COLORSPACE_YUYV, stringify(IMAGE_UTIL_COLORSPACE_YUYV), }, + { IMAGE_UTIL_COLORSPACE_RGB565, stringify(IMAGE_UTIL_COLORSPACE_RGB565), }, + { IMAGE_UTIL_COLORSPACE_RGB888, stringify(IMAGE_UTIL_COLORSPACE_RGB888), }, + { IMAGE_UTIL_COLORSPACE_ARGB8888, stringify(IMAGE_UTIL_COLORSPACE_ARGB8888), }, + { IMAGE_UTIL_COLORSPACE_BGRA8888, stringify(IMAGE_UTIL_COLORSPACE_BGRA8888), }, + { IMAGE_UTIL_COLORSPACE_RGBA8888, stringify(IMAGE_UTIL_COLORSPACE_RGBA8888), }, + { IMAGE_UTIL_COLORSPACE_BGRX8888, stringify(IMAGE_UTIL_COLORSPACE_BGRX8888), }, + }; + + int i = 0; + + for ( i = 0 ; i < sizeof(list)/sizeof(list[0]); i++) + { + if ( list[i].color == colorspace ) + { + printf("Supported : %s\n", list[i].name); + break; + } + } + + return true; +} +#endif + + +int read_jpeg_file( char *filename, char **buf, int *w, int *h, int *bufsize ) +{ + /* these are standard libjpeg structures for reading(decompression) */ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + /* libjpeg data structure for storing one row, that is, scanline of an image */ + JSAMPROW row_pointer[1]; + + FILE *infile = fopen( filename, "rb" ); + unsigned long location = 0; + int i = 0; + + if ( !infile ) + { + printf("Error opening jpeg file %s\n!", filename ); + return -1; + } + /* here we set up the standard libjpeg error handler */ + cinfo.err = jpeg_std_error( &jerr ); + /* setup decompression process and source, then read JPEG header */ + jpeg_create_decompress( &cinfo ); + /* this makes the library read from infile */ + jpeg_stdio_src( &cinfo, infile ); + /* reading the image header which contains image information */ + jpeg_read_header( &cinfo, TRUE ); + /* Uncomment the following to output image information, if needed. */ + + /* Start decompression jpeg here */ + jpeg_start_decompress( &cinfo ); + + printf( "JPEG File Information: \n" ); + printf( "Image width and height: %d pixels and %d pixels.\n", cinfo.image_width, cinfo.image_height ); + printf( "Output width and height: %d pixels and %d pixels.\n", cinfo.output_width, cinfo.output_height ); + printf( "Color components per pixel: %d.\n", cinfo.num_components ); + printf( "Color space: %d.\n", cinfo.jpeg_color_space ); + + *w = cinfo.output_width; + *h = cinfo.output_height; + *bufsize = cinfo.output_width*cinfo.output_height*cinfo.num_components; + + unsigned char *outbuf = NULL; + + /* allocate memory to hold the uncompressed image */ + outbuf = (unsigned char*)calloc(1, cinfo.output_width*cinfo.output_height*cinfo.num_components ); + + *buf = outbuf; + + /* now actually read the jpeg into the raw buffer */ + row_pointer[0] = (unsigned char *)calloc(1, cinfo.output_width*cinfo.num_components ); + /* read one scan line at a time */ + while( cinfo.output_scanline < cinfo.image_height ) + { + jpeg_read_scanlines( &cinfo, row_pointer, 1 ); + for( i=0; i<cinfo.image_width*cinfo.num_components;i++) + outbuf[location++] = row_pointer[0][i]; + } + /* wrap up decompression, destroy objects, free pointers and close open files */ + jpeg_finish_decompress( &cinfo ); + jpeg_destroy_decompress( &cinfo ); + free( row_pointer[0] ); + fclose( infile ); + /* yup, we succeeded! */ + return 1; +} + + +void +ConvertRGB565toY(unsigned char* pBuf, unsigned char* pGrayBuf, int width, int height) +{ + unsigned char* pDst, * pEnd; + unsigned short* pSrc; + + unsigned short R, G, B; + long lt; + + pSrc = (unsigned short*) pBuf; + pDst = (unsigned char*) pGrayBuf; + pEnd = (unsigned char*) ((unsigned char*) pGrayBuf + height * width); + + while (pDst < pEnd) + { + R = (unsigned char) ((*pSrc >> 11) << 3); // R + G = (unsigned char) ((*pSrc & 0x07e0) >> 3); // +G + B = (unsigned char) ((*pSrc++ & 0x001f) << 3); // +B + + // Y = 0.299 R + 0.587 G + 0.114 B + lt = (306L * (long) R + 601L * (long) G + 117L * (long) B); + *pDst++ = (unsigned char ) (lt >> 10); + //(BYTE)(((int)R+(int)G+(int)B) /3); + } +} + +void +ConvertARGB8888toY(unsigned char* pBuf, unsigned char* pGrayBuf, int width, int height) +{ + unsigned long* pSrc = (unsigned long*) pBuf; + unsigned char* pDSt = (unsigned char*) pGrayBuf; + unsigned char* pEnd = pDSt + height * width; + + while (pDSt < pEnd) + { + unsigned long r = (*pSrc >> 16) & 0xFF; + unsigned long g = (*pSrc >> 8) & 0xFF; + unsigned long b = (*pSrc++) & 0xFF; + + *pDSt++ = (308 * r + 600 * g + 116 * b) >> 10; + } +} + +#define CLIP(a) ((a) > 255 ? 255 : (a) < 0 ? 0 : (a)) + +void +ConvertRGB888toY(unsigned char* pBuf, unsigned char* pGrayBuf, int width, int height) +{ + unsigned char* pSrc = (unsigned char*) pBuf; + unsigned char* pDSt = (unsigned char*) pGrayBuf; + + unsigned char* pEnd = pDSt + height * width; + + while (pDSt < pEnd) + { + unsigned long r = *pSrc++; + unsigned long g = *pSrc++; + unsigned long b = *pSrc++; + + *pDSt++ = (308 * r + 600 * g + 116 * b) >> 10; + } +} + +void read_raw_file(char *filename, char **buf, int *bufsize ) +{ + FILE *fp; + + fp = fopen(filename, "rb"); + + fseek(fp, 0L, SEEK_END); + long size = ftell(fp); + + fseek(fp, 0L, SEEK_SET); + + + *buf = calloc(1, size); + *bufsize = size; + + fread(buf, 1, size, fp); + + fclose(fp); + +} + +void _save_image(char *filename, void *buf, int len) +{ + FILE *fp; + + fp = fopen(filename, "wb"); + + + fwrite(buf, 1, len, fp); + + fclose(fp); + +} + +void _test_image(char *filename) +{ + unsigned char *buf = NULL; + int nW, nH; + int nBufferSize; + +#if 0 + image_util_foreach_supported_jpeg_colorspace ( _supported_jpeg_colorspace_cb, NULL); + + + int err = 0; + + err = image_util_decode_jpeg(filename, IMAGE_UTIL_COLORSPACE_RGB888, &buf, &nW, &nH, &nBufferSize ); + + if ( err != IMAGE_UTIL_ERROR_NONE ) + { + parse_error(err); + return -1; + } + else + { + printf("Open Success : %s\n", filename); + } +#endif + unsigned char *YBuf; + +#if 1 + read_jpeg_file(filename, &buf, &nW, &nH, &nBufferSize ); + + if ( bSaveRaw == true ) + { + char fname[1024]; + + sprintf(fname, "%s_%dx%d.888", filename, nW, nH); + + _save_image(fname, buf, nW*nH*3); + + printf("Write %s to disk\n", fname); + } + + YBuf = (unsigned char *)calloc(1, nW * nH); + + ConvertRGB888toY(buf, YBuf, nW, nH); + + if ( bSaveRaw == true ) + { + char fname[1024]; + + sprintf(fname, "%s_%dx%d.raw", filename, nW, nH); + + _save_image(fname, YBuf, nW*nH); + + printf("Write %s to disk\n", fname); + } +#else + read_raw_file(filename, &YBuf, &nBufferSize ); +#endif + face_h handle; + + face_create(&handle); + + face_image_h image; + + face_image_create(FACE_IMAGE_COLORSPACE_LUMINANCE_ONLY, YBuf, nW, nH, nW*nH, &image); + + int nCount = 0; + + face_rect_s *rects = NULL; + printf("rects=0x%08x &rects=0x%08x\n", rects, &rects); + + int j = 0; + + for ( j = 0 ; j < 2; j++) + { + + face_detect_faces(handle, FACE_IMAGE_TYPE_SINGLE, image, &rects, &nCount); + + if ( nCount == 0 ) + { + printf("No face is founded\n"); + break; + } + +// rects[0] rects[1] .. rects[nCount -1 ] + + printf("Detected : %d\n", nCount); + + face_component_h component; + + face_expression_e expression; + face_eye_state_e l, r; + face_feature_h feature; + + int i = 0; + for ( i = 0; i < nCount ; i++) + { + face_extract_component(handle, image, &rects[i], &component); + +// face_recognize_expression(handle, image, component, &expression); + +// face_recognize_blink(handle, image, component, &l, &r); + + face_extract_feature(handle, image, component, &feature); + + face_component_destroy(component); + face_feature_destroy(feature); + } + + free(rects); + + } + + face_image_destroy(image); + + free(YBuf); + face_destroy(handle); + +} + +void _test_video(char *filename, int nW, int nH) +{ + unsigned char *buf = NULL; + + FILE *fp; + fp = fopen(filename, "rb"); + + buf = calloc(1, nW * nH * 12 / 8); + + face_h handle; + face_create(&handle); + + int nCount = 0; + + face_rect_s *rects = NULL; + + int j = 0; + + face_rect_s prev_rect, cur_rect; + + face_image_h image; + face_image_h prev_image = NULL; + + int nRead; + + for ( j = 0 ; j < 100; j++) + { + nRead = fread (buf, 1, nW * nH * 12 /8, fp ); + + if ( nRead != nW * nH * 12 /8 ) + { + printf("Try to read %d bytes, but only %d is read\n", nW * nH * 12 /8, nRead); + } + + face_image_create(FACE_IMAGE_COLORSPACE_LUMINANCE_ONLY, buf, nW, nH, nW * nH, &image); + + face_detect_faces(handle, FACE_IMAGE_TYPE_CONTINIOUS, image, &rects, &nCount ); + + if ( nCount != 0 ) + { + face_get_movement(handle, prev_image, image, &prev_rect, &cur_rect); + + prev_rect.x = rects[0].x; + prev_rect.y = rects[0].y; + prev_rect.w = rects[0].w; + prev_rect.h = rects[0].h; + } + + face_image_destroy(prev_image); + prev_image = image; + + + } + + free(buf); + face_destroy(handle); + +} + +int main(int argc, char *argv[]) +{ + printf("Sample FacialEngine is started\n"); + + parse_param(argc, argv); + + if ( filename == NULL ) + { + printf("Cannot found image file\n"); + return -1; + } + + int nW = QCIF_W, nH = QCIF_H; + + if ( bVideo ) + { + _test_video(filename, nW, nH); + } + else + { + _test_image(filename); + } + + printf("Sample FacialEngine is ended\n"); + return -1; +} + + |