summaryrefslogtreecommitdiff
path: root/sample/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'sample/src/main.c')
-rwxr-xr-xsample/src/main.c557
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;
+}
+
+