Renesas GR-PEACH OpenCV Development / gr-peach-opencv-project-sd-card_update

Fork of gr-peach-opencv-project-sd-card by the do

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "DisplayBace.h"
00003 #include "rtos.h"
00004 #include "AsciiFont.h"
00005 #include "define.h"
00006 #include "mStorage.hpp"
00007 
00008 // Include for graphic
00009 #include "graphicFramework/myImage.h"
00010 #include "graphicFramework/mGraphic.hpp"
00011 
00012 // Include for opencv
00013 #include "cProcess/cProcess.hpp"
00014 #include "opencv_3_1/opencv2/core.hpp"
00015 #include "opencv_3_1/opencv2/imgproc.hpp"
00016 #include "opencv_3_1/opencv2/objdetect.hpp"
00017 #include "opencv_3_1/opencv2/face.hpp"
00018 using namespace cv;
00019 using namespace face;
00020 
00021 typedef struct {
00022     int x;
00023     int y;
00024     int radius;
00025     uint8_t color[2];
00026 }mCircle;
00027 
00028 typedef struct {
00029     int x1;
00030     int y1;
00031     int x2;
00032     int y2;
00033     uint8_t color[2];
00034 }mLine;
00035 
00036 typedef struct {
00037     vector<Mat> database_image;
00038     vector<int> database_label;
00039 }face_database_t;
00040 
00041 typedef struct {
00042     Rect obj;
00043     int label;
00044 }obj_detect_result;
00045 
00046 typedef struct {
00047     vector<mCircle> circles;
00048     vector<mLine> lines;
00049     vector<Point> contour;//only have max contour
00050 }gesture_result;
00051 
00052 typedef struct {
00053     vector<Point> Pointstart;
00054     vector<Point> Pointdepth;
00055     vector<int> Pointindex;
00056     int detecthand;
00057 }ConvexPoint;
00058 
00059 typedef struct
00060 {
00061     double hand_max;
00062     double hand_min;
00063 }Sampling;
00064 
00065 /* Hardware */
00066 static DisplayBase Display;
00067 static DigitalOut  lcd_pwon(P7_15);
00068 static DigitalOut  lcd_blon(P8_1);
00069 static PwmOut      lcd_cntrst(P8_15);
00070 static Serial      pc(USBTX, USBRX);
00071 static TouckKey_LCD_shield touch(P4_0, P2_13, I2C_SDA, I2C_SCL);
00072 
00073 /* Semaphore and mutex */
00074 rtos::Mutex mMutexProcess;
00075 rtos::Mutex mMutexObjects;
00076 rtos::Mutex mMutexClicked;
00077 
00078 static Semaphore semProcessThread(0);
00079 static Semaphore semTouch(0);
00080 static Semaphore semDrawAction(0);
00081 
00082 /* Threads */
00083 static Thread *    p_VideoLcdTask = NULL;
00084 static Thread *    p_DrawObjects = NULL;
00085 static Thread *    p_Touch = NULL;
00086 
00087 static cStorage *myStorage = NULL;
00088 static vector<obj_detect_result> gObjectDetects;
00089 static gesture_result gGestureResult;
00090 static bool gIsProcessing = false;
00091 static bool gIsDrawing = false;
00092 static int write_buff_num = 0;
00093 static int read_buff_num = 0;
00094 static bool graphics_init_end = false;
00095 static APP_MODE appMode = GUESTURE_RECOGNITION;
00096 static CLICKED_CODE clickedCode = CLICKED_UNKNOWN;
00097 
00098 /****** cache control ******/
00099 static void dcache_clean(void * p_buf, uint32_t size) {
00100     uint32_t start_addr = (uint32_t)p_buf & 0xFFFFFFE0;
00101     uint32_t end_addr   = (uint32_t)p_buf + size;
00102     uint32_t addr;
00103 
00104     /* Data cache clean */
00105     for (addr = start_addr; addr < end_addr; addr += 0x20) {
00106         __v7_clean_dcache_mva((void *)addr);
00107     }
00108 }
00109 
00110 /****** LCD ******/
00111 #if(0) /* When needing LCD Vsync interrupt, please make it effective. */
00112 static void IntCallbackFunc_LoVsync(DisplayBase::int_type_t int_type) {
00113     /* Interrupt callback function for Vsync interruption */
00114 }
00115 #endif
00116 
00117 static void Init_LCD_Display(void) {
00118     DisplayBase::graphics_error_t error;
00119     DisplayBase::lcd_config_t lcd_config;
00120     PinName lvds_pin[8] = {
00121         /* data pin */
00122         P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0
00123     };
00124 
00125     lcd_pwon = 0;
00126     lcd_blon = 0;
00127     Thread::wait(100);
00128     lcd_pwon = 1;
00129     lcd_blon = 1;
00130 
00131     Display.Graphics_Lvds_Port_Init(lvds_pin, 8);
00132 
00133     /* Graphics initialization process */
00134     lcd_config = LcdCfgTbl_LCD_shield;
00135     error = Display.Graphics_init(&lcd_config);
00136     if (error != DisplayBase::GRAPHICS_OK ) {
00137         printf("Line %d, error %d\n", __LINE__, error);
00138         mbed_die();
00139     }
00140     graphics_init_end = true;
00141 
00142 #if(0) /* When needing LCD Vsync interrupt, please make it effective. */
00143     /* Interrupt callback function setting (Vsync signal output from scaler 0)*/
00144     error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_LO_VSYNC ,
00145                                                     0, IntCallbackFunc_LoVsync);
00146     if (error != DisplayBase::GRAPHICS_OK ) {
00147         printf("Line %d, error %d\n", __LINE__, error);
00148         mbed_die();
00149     }
00150 #endif
00151 }
00152 
00153 static void Start_LCD_Display(uint8_t * p_buf) {
00154     DisplayBase::rect_t rect;
00155 
00156     rect.vs  = 0;
00157     rect.vw  = LCD_PIXEL_HEIGHT;
00158     rect.hs  = 0;
00159     rect.hw  = LCD_PIXEL_WIDTH;
00160     Display.Graphics_Read_Setting(
00161         DisplayBase::GRAPHICS_LAYER_0 ,
00162         (void *)p_buf,
00163         FRAME_BUFFER_STRIDE,
00164         GRAPHICS_FORMAT,
00165         WR_RD_WRSWA,
00166         &rect
00167     );
00168     Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0 );
00169 }
00170 
00171 /****** Video ******/
00172 #if(0) /* When needing video Vsync interrupt, please make it effective. */
00173 static void IntCallbackFunc_ViVsync(DisplayBase::int_type_t int_type) {
00174     /* Interrupt callback function for Vsync interruption */
00175 }
00176 #endif
00177 
00178 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) {
00179     /* Interrupt callback function */
00180 #if VIDEO_INPUT_METHOD == VIDEO_CVBS
00181     if (vfield_count == 0) {
00182         vfield_count = 1;
00183     } else {
00184         vfield_count = 0;
00185 #else
00186     {
00187 #endif
00188         if (p_VideoLcdTask != NULL) {
00189             p_VideoLcdTask->signal_set(1);
00190         }
00191     }
00192 }
00193 
00194 static void Init_Video(void) {
00195     DisplayBase::graphics_error_t error;
00196 
00197     /* Graphics initialization process */
00198     if (graphics_init_end == false) {
00199         /* When not initializing LCD, this processing is needed. */
00200         error = Display.Graphics_init(NULL);
00201         if (error != DisplayBase::GRAPHICS_OK ) {
00202             printf("Line %d, error %d\n", __LINE__, error);
00203             mbed_die();
00204         }
00205         graphics_init_end = true;
00206     }
00207 
00208 #if VIDEO_INPUT_METHOD == VIDEO_CVBS
00209     error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_VDEC , NULL);
00210     if( error != DisplayBase::GRAPHICS_OK  ) {
00211         printf("Line %d, error %d\n", __LINE__, error);
00212         mbed_die();
00213     }
00214 #elif VIDEO_INPUT_METHOD == VIDEO_CMOS_CAMERA
00215     DisplayBase::video_ext_in_config_t ext_in_config;
00216     PinName cmos_camera_pin[11] = {
00217         /* data pin */
00218         P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0,
00219         /* control pin */
00220         P10_0,      /* DV0_CLK   */
00221         P1_0,       /* DV0_Vsync */
00222         P1_1        /* DV0_Hsync */
00223     };
00224 
00225     /* MT9V111 camera input config */
00226     ext_in_config.inp_format      = DisplayBase::VIDEO_EXTIN_FORMAT_BT601 ; /* BT601 8bit YCbCr format */
00227     ext_in_config.inp_pxd_edge    = DisplayBase::EDGE_RISING ;              /* Clock edge select for capturing data          */
00228     ext_in_config.inp_vs_edge     = DisplayBase::EDGE_RISING ;              /* Clock edge select for capturing Vsync signals */
00229     ext_in_config.inp_hs_edge     = DisplayBase::EDGE_RISING ;              /* Clock edge select for capturing Hsync signals */
00230     ext_in_config.inp_endian_on   = DisplayBase::OFF ;                      /* External input bit endian change on/off       */
00231     ext_in_config.inp_swap_on     = DisplayBase::OFF ;                      /* External input B/R signal swap on/off         */
00232     ext_in_config.inp_vs_inv      = DisplayBase::SIG_POL_NOT_INVERTED ;     /* External input DV_VSYNC inversion control     */
00233     ext_in_config.inp_hs_inv      = DisplayBase::SIG_POL_INVERTED ;         /* External input DV_HSYNC inversion control     */
00234     ext_in_config.inp_f525_625    = DisplayBase::EXTIN_LINE_525 ;           /* Number of lines for BT.656 external input */
00235     ext_in_config.inp_h_pos       = DisplayBase::EXTIN_H_POS_CRYCBY ;       /* Y/Cb/Y/Cr data string start timing to Hsync reference */
00236     ext_in_config.cap_vs_pos      = 6;                                     /* Capture start position from Vsync */
00237     ext_in_config.cap_hs_pos      = 150;                                   /* Capture start position form Hsync */
00238 #if (LCD_TYPE == 0)
00239     /* The same screen ratio as the screen ratio of the LCD. */
00240     ext_in_config.cap_width       = 640;                                   /* Capture width */
00241     ext_in_config.cap_height      = 363;                                   /* Capture height Max 468[line]
00242                                                                              Due to CMOS(MT9V111) output signal timing and VDC5 specification */
00243 #else
00244     ext_in_config.cap_width       = 640;                                   /* Capture width  */
00245     ext_in_config.cap_height      = 468;                                   /* Capture height Max 468[line]
00246                                                                              Due to CMOS(MT9V111) output signal timing and VDC5 specification */
00247 #endif
00248     error = Display.Graphics_Video_init( DisplayBase::INPUT_SEL_EXT , &ext_in_config);
00249     if( error != DisplayBase::GRAPHICS_OK  ) {
00250         printf("Line %d, error %d\n", __LINE__, error);
00251         mbed_die();
00252     }
00253 
00254     /* Camera input port setting */
00255     error = Display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11);
00256     if( error != DisplayBase::GRAPHICS_OK  ) {
00257         printf("Line %d, error %d\n", __LINE__, error);
00258         mbed_die();
00259     }
00260 #endif
00261 
00262 #if(0) /* When needing video Vsync interrupt, please make it effective. */
00263     /* Interrupt callback function setting (Vsync signal input to scaler 0) */
00264     error = Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VI_VSYNC ,
00265                                                  0, IntCallbackFunc_ViVsync);
00266     if (error != DisplayBase::GRAPHICS_OK ) {
00267         printf("Line %d, error %d\n", __LINE__, error);
00268         mbed_die();
00269     }
00270 #endif
00271 
00272     /* Interrupt callback function setting (Field end signal for recording function in scaler 0) */
00273     error = Display.Graphics_Irq_Handler_Set(VIDEO_INT_TYPE, 0, 
00274                                                         IntCallbackFunc_Vfield);
00275     if (error != DisplayBase::GRAPHICS_OK ) {
00276         printf("Line %d, error %d\n", __LINE__, error);
00277         mbed_die();
00278     }
00279 }
00280 
00281 static void initDrawResultLayer(void)
00282 {
00283     DisplayBase::rect_t rect;
00284     /* The layer by which the touch panel location is drawn */
00285     memset(user_frame_buffer_draw, 0, sizeof(user_frame_buffer_draw));
00286     dcache_clean(user_frame_buffer_draw, sizeof(user_frame_buffer_draw));
00287     rect.vs  = 0;
00288     rect.vw  = LCD_PIXEL_HEIGHT;
00289     rect.hs  = 0;
00290     rect.hw  = LCD_PIXEL_WIDTH;
00291     Display.Graphics_Read_Setting(
00292         DisplayBase::GRAPHICS_LAYER_1 ,
00293         (void *)user_frame_buffer_draw,
00294         DRAW_BUFFER_STRIDE,
00295         DisplayBase::GRAPHICS_FORMAT_ARGB4444 ,
00296         DisplayBase::WR_RD_WRSWA_32_16BIT ,
00297         &rect
00298     );
00299     Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_1 );
00300 }
00301 
00302 static void initDrawAction(void)
00303 {
00304     // Init draw control
00305     DisplayBase::rect_t rect;
00306     rect.vs  = 0;
00307     rect.vw  = LCD_PIXEL_HEIGHT;
00308     rect.hs  = 0;
00309     rect.hw  = LCD_PIXEL_WIDTH;
00310     
00311     memset(user_frame_buffer_draw_action, 0, 
00312                                         sizeof(user_frame_buffer_draw_action));     
00313     /* Clean cache */
00314     dcache_clean(user_frame_buffer_draw_action, 
00315                                         sizeof(user_frame_buffer_draw_action));
00316     
00317     Display.Graphics_Read_Setting(
00318         DisplayBase::GRAPHICS_LAYER_3 ,
00319         (void *)user_frame_buffer_draw_action,
00320         DRAW_BUFFER_STRIDE,
00321         DisplayBase::GRAPHICS_FORMAT_ARGB4444 ,
00322         DisplayBase::WR_RD_WRSWA_32_16BIT ,
00323         &rect
00324     );
00325     Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_3 );
00326 }
00327 static void initDrawButtonLayer(void)
00328 {
00329     DisplayBase::rect_t rect;
00330     /* The layer by which the touch panel location is drawn */
00331     memset(user_frame_buffer_draw_button, 0, 
00332                                         sizeof(user_frame_buffer_draw_button));
00333     dcache_clean(user_frame_buffer_draw_button, 
00334                                         sizeof(user_frame_buffer_draw_button));
00335     rect.vs  = 0;
00336     rect.vw  = LCD_PIXEL_HEIGHT;
00337     rect.hs  = 0;
00338     rect.hw  = LCD_PIXEL_WIDTH;
00339     Display.Graphics_Read_Setting(
00340         DisplayBase::GRAPHICS_LAYER_2 ,
00341         (void *)user_frame_buffer_draw_button,
00342         DRAW_BUFFER_STRIDE,
00343         DisplayBase::GRAPHICS_FORMAT_ARGB4444 ,
00344         DisplayBase::WR_RD_WRSWA_32_16BIT ,
00345         &rect
00346     );
00347     Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_2 );
00348 }
00349 
00350 static void Start_Video(uint8_t * p_buf) {
00351     DisplayBase::graphics_error_t error;
00352 
00353     /* Video capture setting (progressive form fixed) */
00354     error = Display.Video_Write_Setting(
00355                 VIDEO_INPUT_CH,
00356                 COL_SYS,
00357                 p_buf,
00358                 FRAME_BUFFER_STRIDE,
00359                 VIDEO_FORMAT,
00360                 WR_RD_WRSWA,
00361                 VIDEO_PIXEL_VW,
00362                 VIDEO_PIXEL_HW
00363             );
00364     if (error != DisplayBase::GRAPHICS_OK ) {
00365         printf("Line %d, error %d\n", __LINE__, error);
00366         mbed_die();
00367     }
00368 
00369     /* Video write process start */
00370     error = Display.Video_Start(VIDEO_INPUT_CH);
00371     if (error != DisplayBase::GRAPHICS_OK ) {
00372         printf("Line %d, error %d\n", __LINE__, error);
00373         mbed_die();
00374     }
00375 
00376     /* Video write process stop */
00377     error = Display.Video_Stop(VIDEO_INPUT_CH);
00378     if (error != DisplayBase::GRAPHICS_OK ) {
00379         printf("Line %d, error %d\n", __LINE__, error);
00380         mbed_die();
00381     }
00382 
00383     /* Video write process start */
00384     error = Display.Video_Start(VIDEO_INPUT_CH);
00385     if (error != DisplayBase::GRAPHICS_OK ) {
00386         printf("Line %d, error %d\n", __LINE__, error);
00387         mbed_die();
00388     }
00389 }
00390 
00391 /* Select function from button */
00392 APP_MODE getFunctionSelected(int x, int y)
00393 {
00394     int w = 100; //width of image button
00395     if ( MODE_BTN_Y > y )
00396     {
00397         return MODE_UNKNOWN;
00398     }
00399     
00400     if ( MODE_BTN_X <= x && x <= (MODE_BTN_X + w))
00401     {
00402         return FACE_DETECTION;
00403     }
00404     else if ( (2*MODE_BTN_X + w) <= x && x <= (2*MODE_BTN_X + 2*w))
00405     {
00406         return FACE_RECOGNITION;
00407     }
00408     else if ( (3*MODE_BTN_X + 2*w) <= x && x <= (3*MODE_BTN_X + 3*w) )
00409     {
00410         return MOTION_DETECTION;
00411     }
00412     else if ((4*MODE_BTN_X + 3*w) <= x && x <= (4*MODE_BTN_X + 4*w))
00413     {
00414         return GUESTURE_RECOGNITION;
00415     }
00416     else
00417         return MODE_UNKNOWN;
00418 }
00419 
00420 /* Click action in face recognition */
00421 void clickActionFaceReg(int x, int y)
00422 {
00423     mMutexClicked.lock();
00424     if(REGIS_FACE_BTN_X <= x && x <= (REGIS_FACE_BTN_X + 30) &&
00425        REGIS_FACE_BTN_Y <= y && y <= (REGIS_FACE_BTN_Y + 30))
00426     {
00427         clickedCode = CLICKED_REGIS_FACE;
00428     }
00429     else if (FACE_REG_ACT_MENU_X <= x && x <= (FACE_REG_ACT_MENU_X + 60) &&
00430         FACE_REG_ACT_MENU_Y <= y && y <= (FACE_REG_ACT_MENU_Y + 20))
00431     {
00432         clickedCode = CLICKED_CHANGE_ID;
00433     }
00434     else if (FACE_REG_ACT_MENU_X <= x && x <= (FACE_REG_ACT_MENU_X + 60) &&
00435         (FACE_REG_ACT_MENU_Y + 20 + 12)<= y && 
00436         y <= (FACE_REG_ACT_MENU_Y + 2*20 + 12))//space:12
00437     {
00438         clickedCode = CLICKED_ADD;
00439     }
00440     else if (FACE_REG_ACT_MENU_X <= x && x <= (FACE_REG_ACT_MENU_X + 60) &&
00441         (FACE_REG_ACT_MENU_Y + 2*20 + 2*12)<= y && 
00442         y <= (FACE_REG_ACT_MENU_Y + 3*20 + 2*12))
00443     {
00444         clickedCode = CLICKED_IGNORE;
00445     }
00446     else
00447     {
00448         clickedCode = CLICKED_UNKNOWN;
00449     }
00450     mMutexClicked.unlock();
00451 }
00452 
00453 /* Click on screen gesture recognition */
00454 void clickActionGestureReg(int x, int y)
00455 {
00456     mMutexClicked.lock();
00457     if(GESTURE_SAMPLING_BTN_X <= x && x <= (GESTURE_SAMPLING_BTN_X + 60) &&
00458        GESTURE_SAMPLING_BTN_Y <= y && y <= (GESTURE_SAMPLING_BTN_Y + 20))
00459     {
00460         clickedCode = CLICKED_HAND_SAMPLING;
00461     }
00462     else
00463     {
00464         clickedCode = CLICKED_UNKNOWN;
00465     }
00466     mMutexClicked.unlock();
00467 }
00468 
00469 /**** Draw button controls ****/
00470 void drawButtonControls(graphicFrameworkCanvas myCanvasButton)
00471 {
00472     int space = 16;
00473     int x = 0;
00474     int y = MODE_BTN_Y;
00475     
00476     x+=space;
00477     myCanvasButton.drawImage(my_img_button_face_detect,x,y); // 100x40
00478     x+=100;
00479     
00480     x+=space;
00481     myCanvasButton.drawImage(my_img_button_face_recognition,x,y);
00482     x+=100;
00483 
00484     x+=space;
00485     myCanvasButton.drawImage(my_img_button_obj_motion,x,y);
00486     x+=100;
00487     
00488     x+=space;
00489     myCanvasButton.drawImage(my_img_button_gesture_reg,x,y);
00490     x+=100;
00491 }
00492 
00493 void drawTextScreen(graphicFrameworkCanvas myCanvasButton)
00494 {
00495     int x = 160;
00496     int y = 5;
00497     
00498     if( appMode == MOTION_DETECTION )
00499     {
00500         myCanvasButton.drawImage(my_img_text_obj_motion,x, y);
00501     }
00502     else if ( appMode == FACE_DETECTION )
00503     {
00504         myCanvasButton.drawImage(my_img_text_face_detection,x, y);
00505     }
00506     else if ( appMode == FACE_RECOGNITION )
00507     {
00508         myCanvasButton.drawImage(my_img_text_face_recognition,x, y);
00509     }
00510     else if ( appMode == GUESTURE_RECOGNITION )
00511     {
00512         myCanvasButton.drawImage(my_img_text_gesture_reg,x, y);
00513     }
00514 }
00515 
00516 void clearGestureResult(gesture_result res)
00517 {
00518     res.circles.clear();
00519     res.lines.clear();
00520     res.contour.clear();
00521 }
00522 /****** Thread image process ******/
00523 static void img_draw_objects(void)
00524 {
00525     graphicFrameworkCanvas myCanvas(user_frame_buffer_draw, 0x01E0,
00526                     0x0110, (uint8_t)DRAW_BUFFER_BYTE_PER_PIXEL, 
00527                     (uint8_t)DRAW_POINT,0x06);
00528 
00529     initDrawResultLayer();
00530     
00531     uint8_t color[2] = {0x0B,0xFF};// Color Pink
00532     APP_MODE oldMode = appMode;
00533     while(1)
00534     {
00535         Thread::signal_wait(1);        
00536         memset(user_frame_buffer_draw, 0, sizeof(user_frame_buffer_draw));
00537 
00538         if ( oldMode != appMode)
00539         {
00540             oldMode = appMode;
00541             
00542             mMutexObjects.lock();
00543             gIsDrawing = false;
00544             mMutexObjects.unlock();     
00545                    
00546             // Data cache clean 
00547             dcache_clean(user_frame_buffer_draw, sizeof(user_frame_buffer_draw));
00548             continue;
00549         }
00550 
00551         // Draw faces on screen
00552         switch(appMode)
00553         {
00554             case FACE_DETECTION:
00555             case MOTION_DETECTION:
00556             {
00557                 if(gObjectDetects.size() > 0)
00558                 {
00559                     for(int i = 0;i < gObjectDetects.size();i++)
00560                     {
00561                         int _x = gObjectDetects[i].obj.x*IMG_DOWN_SAMPLE;
00562                         int _y = gObjectDetects[i].obj.y*IMG_DOWN_SAMPLE;
00563                         int _w = gObjectDetects[i].obj.width*IMG_DOWN_SAMPLE;
00564                         int _h = gObjectDetects[i].obj.height*IMG_DOWN_SAMPLE;
00565                         myCanvas.drawRect(_x,_y,_w,_h,color);
00566                     }
00567                 }
00568                 gObjectDetects.clear();
00569                 break;
00570             }
00571             case FACE_RECOGNITION:
00572             {
00573                 if(gObjectDetects.size() > 0)
00574                 {
00575                     for(int i = 0;i < gObjectDetects.size();i++)
00576                     {
00577                         int _x = gObjectDetects[i].obj.x*IMG_DOWN_SAMPLE;
00578                         int _y = gObjectDetects[i].obj.y*IMG_DOWN_SAMPLE;
00579                         int _w = gObjectDetects[i].obj.width*IMG_DOWN_SAMPLE;
00580                         int _h = gObjectDetects[i].obj.height*IMG_DOWN_SAMPLE;
00581                         if(gObjectDetects[i].label == 1)
00582                         {
00583                             // Yellow
00584                             color[0] = 0xF0;
00585                             color[1] = 0xFF;
00586                         }
00587                         else if (gObjectDetects[i].label == 2)
00588                         {
00589                             // Green
00590                             color[0] = 0xF0;
00591                             color[1] = 0xF0;
00592                         }
00593                         else
00594                         {
00595                             // Pink
00596                             color[0] = 0x0B;
00597                             color[1] = 0xFF;
00598                         }
00599                         myCanvas.drawRect(_x,_y,_w,_h,color);
00600                     }
00601                 }
00602                 gObjectDetects.clear();
00603                 break;
00604             }
00605             case GUESTURE_RECOGNITION:
00606             {
00607                 uint8_t contoursColor[2] = {0xF0,0xFF};
00608                     
00609                 //Draw max contour
00610                 for(int i = 0; i < gGestureResult.contour.size();i++)//i=0
00611                 {
00612                     myCanvas.draw_pixel(gGestureResult.contour[i].x,
00613                             gGestureResult.contour[i].y,contoursColor);
00614                 }
00615                 // Draw lines, circles
00616                 for(int i = 0;i < gGestureResult.lines.size();i++)
00617                 {
00618                     myCanvas.drawLine(gGestureResult.lines[i].x1,
00619                                       gGestureResult.lines[i].y1,
00620                                       gGestureResult.lines[i].x2,
00621                                       gGestureResult.lines[i].y2,
00622                                       gGestureResult.lines[i].color);
00623                 }
00624                 
00625                 for(int i = 0;i < gGestureResult.circles.size();i++)
00626                 {
00627                     myCanvas.drawCircle(gGestureResult.circles[i].x,
00628                                         gGestureResult.circles[i].y,
00629                                         gGestureResult.circles[i].radius,
00630                                         gGestureResult.circles[i].color);
00631                 }
00632                 break;
00633             }
00634             default:
00635             break;
00636         } // switch
00637 
00638         mMutexObjects.lock();
00639         gIsDrawing = false;
00640         mMutexObjects.unlock();
00641         
00642         // Data cache clean 
00643         dcache_clean(user_frame_buffer_draw, sizeof(user_frame_buffer_draw));
00644     }//while
00645 }
00646 
00647 /* Touch task*/
00648 static void touch_int_callback(void) 
00649 {
00650     semTouch.release();
00651 }
00652 static void touch_task(void) 
00653 {
00654     graphicFrameworkCanvas myCanvasButton(user_frame_buffer_draw_button, 0x01E0,
00655                     0x0110, (uint8_t)DRAW_BUFFER_BYTE_PER_PIXEL, 
00656                     (uint8_t)DRAW_POINT,0x06);
00657     TouchKey::touch_pos_t touch_pos[TOUCH_NUM];
00658     
00659     /* Callback setting */
00660     touch.SetCallback(&touch_int_callback);
00661 
00662     /* Reset touch IC */
00663     touch.Reset();
00664     
00665     initDrawButtonLayer();
00666     drawTextScreen(myCanvasButton);
00667     drawButtonControls(myCanvasButton);
00668     
00669     int x_touch = -1, y_touch = -1;
00670 
00671     set_time(0);//set_time(1498450609);//11:15,Mon-26-June
00672     double seconds = (double)time(NULL);
00673 
00674     while(1)
00675     {
00676         /* Wait touch event */
00677         semTouch.wait();
00678 
00679         touch.GetCoordinates(TOUCH_NUM, touch_pos);
00680 
00681         for (int i = 0; i < TOUCH_NUM; i ++) {
00682             if (touch_pos[i].valid) {
00683                 int new_touch_x = touch_pos[i].x;
00684                 int new_touch_y = touch_pos[i].y;
00685                 APP_MODE mode = getFunctionSelected(new_touch_x, new_touch_y);
00686 
00687                 if(mode != appMode && mode != MODE_UNKNOWN)
00688                 {
00689                     appMode = mode;
00690                     memset(user_frame_buffer_draw_button, 0, sizeof(uint8_t)*LCD_PIXEL_WIDTH*(MODE_BTN_Y)*FRAME_BUFFER_BYTE_PER_PIXEL);
00691                     drawTextScreen(myCanvasButton);
00692                     dcache_clean(user_frame_buffer_draw_button, sizeof(user_frame_buffer_draw_button));
00693                 }
00694                 else if (appMode == FACE_RECOGNITION)
00695                 {
00696                     double time_1 = (double)time(NULL) - seconds;
00697                     int posAbs = abs(new_touch_x - x_touch) + 
00698                                       abs(new_touch_y - y_touch); 
00699                     
00700                     if(posAbs > 5 || time_1 > 0.5) //1s
00701                     {
00702                         x_touch = new_touch_x;
00703                         y_touch = new_touch_y;
00704 
00705                         clickActionFaceReg(new_touch_x,new_touch_y);
00706 
00707                     }
00708                     seconds = (double)time(NULL);
00709                 }
00710                 else if (appMode == GUESTURE_RECOGNITION)
00711                 {
00712                     double time_1 = (double)time(NULL) - seconds;
00713                     int posAbs = abs(new_touch_x - x_touch) + 
00714                                       abs(new_touch_y - y_touch); 
00715 
00716                     if(posAbs > 5 || time_1 > 0.5) //1s
00717                     {
00718                         x_touch = new_touch_x;
00719                         y_touch = new_touch_y;
00720                         clickActionGestureReg(new_touch_x,new_touch_y);
00721                     }
00722 
00723                     seconds = (double)time(NULL);
00724                 }
00725             }
00726         }
00727     }
00728 }
00729 
00730 /****** Video input is output to LCD ******/
00731 static void video_lcd_task(void) {
00732     DisplayBase::graphics_error_t error;
00733     int wk_num;
00734 
00735     /* Initialization memory */
00736     for (int i = 0; i < FRAME_BUFFER_NUM; i++) {
00737         memset(FrameBufferTbl[i], 0, (FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT));
00738         dcache_clean(FrameBufferTbl[i],(FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT));
00739     }
00740 
00741     /* Start of Video */
00742     Start_Video(FrameBufferTbl[write_buff_num]);
00743 
00744     /* Wait for first video drawing */
00745     Thread::signal_wait(1);
00746     write_buff_num++;
00747     if (write_buff_num >= FRAME_BUFFER_NUM) {
00748         write_buff_num = 0;
00749     }
00750     error = Display.Video_Write_Change(VIDEO_INPUT_CH, 
00751                         FrameBufferTbl[write_buff_num], FRAME_BUFFER_STRIDE);
00752     if (error != DisplayBase::GRAPHICS_OK ) {
00753         printf("Line %d, error %d\n", __LINE__, error);
00754         mbed_die();
00755     }
00756 
00757     /* Start of LCD */
00758     Start_LCD_Display(FrameBufferTbl[read_buff_num]);
00759 
00760     /* Backlight on */
00761     Thread::wait(200);
00762     lcd_cntrst.write(1.0);
00763 
00764     while (1) {
00765         Thread::signal_wait(1);
00766         wk_num = write_buff_num + 1;
00767         if (wk_num >= FRAME_BUFFER_NUM) {
00768             wk_num = 0;
00769         }
00770         /* If the next buffer is empty, it's changed. */
00771         if (wk_num != read_buff_num) {
00772             read_buff_num  = write_buff_num;
00773             write_buff_num = wk_num;
00774             
00775             /* Change video buffer */
00776             error = Display.Video_Write_Change(VIDEO_INPUT_CH, 
00777                     FrameBufferTbl[0/*write_buff_num*/], FRAME_BUFFER_STRIDE);
00778             if (error != DisplayBase::GRAPHICS_OK ) {
00779                 printf("Line %d, error %d\n", __LINE__, error);
00780                 mbed_die();
00781             }
00782             
00783             mMutexProcess.lock();
00784             if ( gIsProcessing == false)
00785             {
00786                 gIsProcessing = true;    
00787                 mMutexProcess.unlock();
00788 
00789                 memcpy((void *)my_frame,(void*)FrameBufferTbl[0],
00790                                         FRAME_BUFFER_STRIDE * LCD_PIXEL_HEIGHT);
00791                 semProcessThread.release();
00792             }
00793             else
00794             {
00795                 mMutexProcess.unlock();
00796             }
00797             
00798             /* Change LCD buffer */
00799             Display.Graphics_Read_Change(DisplayBase::GRAPHICS_LAYER_0 , 
00800                                     (void *)FrameBufferTbl[0/*read_buff_num*/]);
00801         }
00802     }
00803 }
00804 
00805 bool initSdCard()
00806 {
00807     if(myStorage == NULL)
00808     {
00809         return false;
00810     }
00811     if (myStorage->isConnectSdCard() == STORG_PASS) 
00812     {
00813         if(myStorage->mountSdCard() == STORG_PASS)
00814         {
00815             return true;
00816         }
00817         else
00818         {
00819             // mount sdcard failed!
00820             return false;
00821         }
00822     }
00823     else
00824     {
00825         // no sdcard!
00826         togle_led(LED_RED);
00827         return false;
00828     }
00829 }
00830 void faceDectectionApp(void)
00831 {
00832     Size face_size(LCD_PIXEL_WIDTH/IMG_DOWN_SAMPLE,
00833                                             LCD_PIXEL_HEIGHT/IMG_DOWN_SAMPLE);
00834     Mat smallImage = Mat::zeros(face_size, CV_8UC1);
00835     CascadeClassifier haar_cascade;
00836     vector<Rect> faces;
00837     if (!haar_cascade.load("/SD/lbpcascade_frontalface.xml"))
00838     {
00839         // load failed
00840         togle_led(LED_RED);
00841         while(1)
00842         {
00843             wait(0.5);
00844         }
00845     }
00846     else{
00847         togle_led(LED_GREEN);
00848     }
00849     togle_reset(LED_RED,LED_BLUE);
00850     faces.clear();
00851     
00852     gObjectDetects.clear();
00853     while (1) {
00854         semProcessThread.wait();
00855         
00856         if ( appMode != FACE_DETECTION )
00857         {
00858             mMutexProcess.lock();
00859             gIsProcessing = false;
00860             mMutexProcess.unlock();
00861             break;
00862         }
00863         
00864         Mat gray;
00865         {
00866             Mat res = _m_cvtRgb5652Rgb(my_frame,(int)LCD_PIXEL_WIDTH,
00867                                                     (int)LCD_PIXEL_HEIGHT,2);
00868             cvtColor(res,gray,COLOR_RGB2GRAY);
00869             res.release();
00870         }
00871 
00872         equalizeHist(gray,gray);
00873         resize(gray, smallImage, face_size);
00874 
00875         haar_cascade.detectMultiScale(smallImage,faces,1.1,
00876                                         2,0|CV_HAAR_SCALE_IMAGE,Size(10,10));        
00877         mMutexObjects.lock();
00878         if(gIsDrawing == false)
00879         {
00880             mMutexObjects.unlock();
00881             for(int i = 0;i < faces.size();i++)
00882             {
00883                 obj_detect_result tmp;
00884                 tmp.obj = faces[i];
00885                 tmp.label = -1;
00886                 gObjectDetects.push_back(tmp);
00887             }
00888             //gObjectDetects = faces;
00889             gIsDrawing = true;
00890             p_DrawObjects->signal_set(1);
00891         }
00892         else
00893         {
00894             mMutexObjects.unlock();
00895         }
00896 
00897         /* Reset flag */
00898         faces.clear();
00899         mMutexProcess.lock();
00900         gIsProcessing = false;
00901         mMutexProcess.unlock();
00902     };
00903 }
00904 
00905 void motionDetectionApp(void)
00906 {
00907     bool isNewStart = true;
00908     int threshValue = 30;
00909     int blurSize = 5;
00910     float mArea = 0.0;
00911     float mMaxArea = 0.0;
00912     int mMaxIndex = 0;
00913     bool _isDrawing;
00914     int mCounter = 0;
00915     Mat curFrameGray;
00916     Mat prevFrameGray;
00917     Mat diffImage;
00918     Mat binImage;
00919     vector<vector<Point> > contours;
00920     vector<Rect> _objects;
00921 
00922     gObjectDetects.clear();
00923     while(1)
00924     {
00925         semProcessThread.wait();
00926         
00927         if ( appMode != MOTION_DETECTION )
00928         {
00929             mMutexProcess.lock();
00930             gIsProcessing = false;
00931             mMutexProcess.unlock();
00932             
00933             break;
00934         }
00935 
00936         _objects.clear();
00937         mCounter++;
00938         if( isNewStart == false)
00939         {
00940             {
00941                 Mat res = _m_cvtRgb5652Rgb(my_frame,(int)LCD_PIXEL_WIDTH,
00942                                                     (int)LCD_PIXEL_HEIGHT,2);
00943                 cvtColor(res,curFrameGray,COLOR_RGB2GRAY);
00944                 res.release();
00945             }
00946             /* differential between foreground and background */
00947             absdiff(curFrameGray, prevFrameGray, diffImage);
00948             blur(diffImage, diffImage, Size(blurSize, blurSize));
00949             threshold(diffImage, binImage, threshValue, 255, CV_THRESH_BINARY);
00950             findContours(binImage, contours, CV_RETR_EXTERNAL, 
00951                                                         CV_CHAIN_APPROX_NONE);
00952 
00953             if(contours.size() > 0)
00954             {
00955                 for (int i = 0; i < contours.size(); i++)
00956                 {
00957                     mArea = contourArea(contours[i]);
00958                     if (mArea > mMaxArea)
00959                     {
00960                         mMaxArea = mArea;
00961                         mMaxIndex = i;
00962                     }
00963                 }
00964                 
00965                 if (mMaxArea > MAX_COUNTOURS)
00966                 {
00967                     Rect objectBoundingRectangle = boundingRect(
00968                                                         contours.at(mMaxIndex));
00969                     _objects.push_back(objectBoundingRectangle);
00970                 }
00971             }
00972             
00973             /* Set display motion objects */
00974             mMutexObjects.lock();
00975             _isDrawing = gIsDrawing;
00976             mMutexObjects.unlock();
00977             
00978             if(_isDrawing == false)
00979             {
00980                 for(int i = 0;i < _objects.size();i++)
00981                 {
00982                     obj_detect_result tmp;
00983                     tmp.obj = _objects[i];
00984                     tmp.label = -1;
00985                     gObjectDetects.push_back(tmp);
00986                 }
00987                 //gObjectDetects = _objects;
00988                 gIsDrawing = true;
00989                 p_DrawObjects->signal_set(1);
00990             }
00991             
00992             /* Reset values */
00993             mMaxArea = 0;
00994             mArea = 0;
00995             mMaxIndex = 0;
00996             
00997             /* Update background */
00998             if(mCounter == 50)
00999             {
01000                 mCounter = 0;
01001                 isNewStart = true;
01002             }
01003         }
01004         else
01005         {
01006             isNewStart = false;
01007             prevFrameGray = _m_cvtRgb5652Rgb(my_frame,(int)LCD_PIXEL_WIDTH,
01008                                                     (int)LCD_PIXEL_HEIGHT,2);
01009             cvtColor(prevFrameGray,prevFrameGray,COLOR_RGB2GRAY);
01010         }
01011         
01012         mMutexProcess.lock();
01013         gIsProcessing = false;
01014         mMutexProcess.unlock();
01015     };
01016 }
01017 
01018 void faceRecognitionApp(void)
01019 {
01020     // Init draw
01021     graphicFrameworkCanvas myCanvas(user_frame_buffer_draw_action, 0x01E0,
01022                     0x0110, (uint8_t)DRAW_BUFFER_BYTE_PER_PIXEL, 
01023                     (uint8_t)DRAW_POINT,0x06);
01024 
01025     uint8_t label_id = 1;
01026     bool oldStateFace = false;// no faces
01027     // End init draw
01028     
01029     Size face_size(LCD_PIXEL_WIDTH/IMG_DOWN_SAMPLE,
01030                                             LCD_PIXEL_HEIGHT/IMG_DOWN_SAMPLE);
01031     Mat smallImage = Mat::zeros(face_size, CV_8UC1);
01032     CascadeClassifier haar_cascade;
01033     vector<Rect> faces;
01034     
01035     //Init recognizer
01036     int radius = 2, neighbors = 4, gridx = 8, gridy = 8, thresmax = 50;
01037     Ptr<LBPHFaceRecognizer> modelReg = createLBPHFaceRecognizer (radius, neighbors,
01038                                     gridx, gridy, thresmax);
01039     face_database_t face_database;
01040     Size regSize(70,70);
01041     bool flag_class = false;
01042     bool flag_train = false;
01043     bool isFirstTrain = true;
01044     bool changeApp = false;
01045     
01046     if (!haar_cascade.load("/SD/lbpcascade_frontalface.xml"))
01047     {
01048         // load failed
01049         togle_led(LED_RED);
01050         while(1)
01051         {
01052             wait(0.5);
01053         }
01054     }
01055     else{
01056         togle_led(LED_GREEN);
01057     }
01058     togle_reset(LED_RED,LED_BLUE);
01059     faces.clear();
01060     
01061     gObjectDetects.clear();
01062     while(1)
01063     {
01064         semProcessThread.wait();
01065 
01066         if ( appMode != FACE_RECOGNITION )
01067         {
01068             mMutexProcess.lock();
01069             gIsProcessing = false;
01070             mMutexProcess.unlock();
01071             memset(user_frame_buffer_draw_action, 0, 
01072                                     sizeof(user_frame_buffer_draw_action));     
01073             break;
01074         }
01075         
01076         Mat gray;
01077         Mat imgRgb = _m_cvtRgb5652Rgb(my_frame,(int)LCD_PIXEL_WIDTH,
01078                                                     (int)LCD_PIXEL_HEIGHT,2);
01079         cvtColor(imgRgb,gray,COLOR_RGB2GRAY);
01080 
01081         equalizeHist(gray,gray);
01082         resize(gray, smallImage, face_size);
01083 
01084         haar_cascade.detectMultiScale(smallImage,faces,1.1,
01085                                         2,0|CV_HAAR_SCALE_IMAGE,Size(10,10));
01086         
01087         mMutexObjects.lock();
01088         if(gIsDrawing == false)
01089         {
01090             mMutexObjects.unlock();
01091 
01092             if( faces.size() > 0)
01093             {
01094                 // Show label
01095                 if (oldStateFace == false)
01096                 {
01097                     oldStateFace = true;
01098                     myCanvas.drawImage(my_img_register_face,    
01099                                         REGIS_FACE_BTN_X ,REGIS_FACE_BTN_Y);
01100                 }
01101                 
01102                 // Click update database
01103                 mMutexClicked.lock();
01104                 if(clickedCode == CLICKED_REGIS_FACE)
01105                 {
01106                     mMutexClicked.unlock();
01107                     
01108                     // Clean draw faces
01109                     mMutexObjects.lock();
01110                     if(gIsDrawing == false)
01111                     {
01112                         mMutexObjects.unlock();
01113                         gObjectDetects.clear();
01114                         gIsDrawing = true;
01115                         p_DrawObjects->signal_set(1);
01116                     }
01117                     else
01118                     {
01119                         mMutexObjects.unlock();
01120                     }
01121 
01122                     // Update database/ train data
01123                     face_database.database_image.clear();
01124                     face_database.database_label.clear();
01125                     flag_train = false;
01126                     
01127                     for (int i = 0; i < faces.size(); i++)
01128                     {
01129                         // Check exit app
01130                         if(changeApp == true)
01131                         {
01132                             break;
01133                         }
01134                         mMutexClicked.lock();
01135                         clickedCode = CLICKED_REGIS_FACE;
01136                         mMutexClicked.unlock();
01137                         
01138                         int _x = faces[i].x*IMG_DOWN_SAMPLE;
01139                         int _y = faces[i].y*IMG_DOWN_SAMPLE;
01140                         int _w = faces[i].width*IMG_DOWN_SAMPLE;
01141                         int _h = faces[i].height*IMG_DOWN_SAMPLE;
01142                         
01143                         Rect roi(_x,_y,_w,_h);
01144                         
01145                         Mat imgShow = imgRgb(roi);
01146                         if(_w > 100)
01147                         {
01148                             resize(imgShow,imgShow,Size(100,100));
01149                             _w = 100;
01150                             _h = 100;
01151                         }
01152 
01153                         uint8_t* src = cvtMat2RGBA444(_w,_h,imgShow);
01154                         
01155                         label_id = 1;
01156                         
01157                         memset(user_frame_buffer_draw_action, 0, 
01158                                     sizeof(user_frame_buffer_draw_action));
01159                         myCanvas.drawImage(src,100, 90);
01160                         myCanvas.drawImage(my_img_id_01,    
01161                                         FACE_REG_ID_MENU_X ,FACE_REG_ID_MENU_Y);
01162                         myCanvas.drawImage(my_img_change_id,    
01163                                 FACE_REG_ACT_MENU_X ,FACE_REG_ACT_MENU_Y);
01164                         myCanvas.drawImage(my_img_add_this,    
01165                             FACE_REG_ACT_MENU_X ,FACE_REG_ACT_MENU_Y + 12 + 20);
01166                         myCanvas.drawImage(my_img_ignore,    
01167                             FACE_REG_ACT_MENU_X ,FACE_REG_ACT_MENU_Y+ 24 + 40);
01168                         
01169                         /* Clean cache */
01170                         dcache_clean(user_frame_buffer_draw_action, 
01171                                     sizeof(user_frame_buffer_draw_action));
01172                         while(1)
01173                         {             
01174                             bool isBreak = false;               
01175                             mMutexClicked.lock();
01176                             CLICKED_CODE codeTmp = clickedCode;
01177                             mMutexClicked.unlock();
01178                             
01179                             // Check exit app
01180                             if ( appMode != FACE_RECOGNITION )
01181                             {
01182                                 changeApp = true;     
01183                                 isBreak = true;
01184                                 break;
01185                             }
01186                             
01187                             switch(codeTmp)
01188                             {
01189                                 case CLICKED_CHANGE_ID:
01190                                 {
01191                                     memset(user_frame_buffer_draw_action + FACE_REG_ID_MENU_Y*2*LCD_PIXEL_WIDTH, 0, 
01192                                                     21*2*LCD_PIXEL_WIDTH);// clear 21 lines
01193                                     // Change ID label
01194                                     if(label_id == 1)
01195                                     {
01196                                         label_id = 2;
01197                                         myCanvas.drawImage(my_img_id_02,    
01198                                             FACE_REG_ID_MENU_X ,FACE_REG_ID_MENU_Y);
01199                                     }
01200                                     else
01201                                     {
01202                                         label_id = 1;
01203                                         myCanvas.drawImage(my_img_id_01,
01204                                             FACE_REG_ID_MENU_X ,FACE_REG_ID_MENU_Y);
01205                                     }
01206                                     
01207                                     /* Clean cache */
01208                                     dcache_clean(user_frame_buffer_draw_action, 
01209                                             sizeof(user_frame_buffer_draw_action));
01210                                             
01211                                     clickedCode = CLICKED_UNKNOWN;
01212                                     break;
01213                                 }
01214                                 case CLICKED_ADD:
01215                                 {
01216                                     
01217                                     Mat imgReg = gray(roi);
01218                                     resize(imgReg,imgReg,regSize);
01219                                     //train face
01220                                     face_database.database_image.push_back(imgReg);
01221                                     face_database.database_label.push_back(label_id);
01222                                     flag_train = true;
01223                                     isBreak = true;
01224                                     break;
01225                                 }
01226                                 case CLICKED_IGNORE:
01227                                 {
01228                                     //ignore
01229                                     isBreak = true;
01230                                     break;
01231                                 }
01232                                 default:
01233                                 break;
01234                             }
01235                             
01236                             if(isBreak)
01237                                 break;
01238                             wait(0.1);
01239                         }
01240                     }// for faces.size()
01241                     
01242                     if( flag_train == true)
01243                     {
01244                         if(isFirstTrain == true)
01245                         {
01246                             isFirstTrain = false;
01247                             modelReg->train(face_database.database_image, face_database.database_label);
01248                         }
01249                         else
01250                         {
01251                             modelReg->update(face_database.database_image, face_database.database_label);
01252                         }
01253                     }
01254                     
01255                     // Clean screen
01256                     memset(user_frame_buffer_draw_action, 0, 
01257                                     sizeof(user_frame_buffer_draw_action));
01258                     oldStateFace = false;
01259 
01260                     mMutexClicked.lock();
01261                     clickedCode = CLICKED_UNKNOWN;
01262                     mMutexClicked.unlock();
01263                 } //clickedCode == CLICKED_REGIS_FACE
01264                 else
01265                 {   
01266                     mMutexClicked.unlock();
01267                     if (isFirstTrain == false)
01268                     {
01269                         for(int i = 0; i < faces.size();i++)
01270                         {
01271                             int _x = faces[i].x*IMG_DOWN_SAMPLE;
01272                             int _y = faces[i].y*IMG_DOWN_SAMPLE;
01273                             int _w = faces[i].width*IMG_DOWN_SAMPLE;
01274                             int _h = faces[i].height*IMG_DOWN_SAMPLE;
01275                             
01276                             Rect roi(_x,_y,_w,_h);
01277                             Mat target_face = gray(roi);
01278                             resize(target_face,target_face,regSize);
01279                             int predicted = -1;
01280                             double confidence_level = 0;
01281                             modelReg->predict(target_face, predicted, confidence_level);
01282                             
01283                             obj_detect_result tmp;
01284                             tmp.obj = faces[i];
01285                  
01286                             if(predicted != -1)
01287                             {
01288                                 if (confidence_level < thresmax)
01289                                 {
01290                                     tmp.label = predicted;
01291                                 }
01292                                 else
01293                                 {
01294                                     tmp.label = -1;
01295                                 }
01296                             }
01297                             else
01298                             {
01299                                 tmp.label = -1;
01300                             }
01301                             gObjectDetects.push_back(tmp);
01302                         }
01303                     }
01304                     else{
01305                         for(int i = 0;i < faces.size();i++)
01306                         {
01307                             obj_detect_result tmp;
01308                             tmp.obj = faces[i];
01309                             tmp.label = -1;
01310                             gObjectDetects.push_back(tmp);
01311                         }
01312                     }
01313                     
01314                     gIsDrawing = true;
01315                     p_DrawObjects->signal_set(1);
01316                 }
01317             } //faces.size() > 0
01318             else
01319             {
01320                 oldStateFace = false;
01321                 memset(user_frame_buffer_draw_action, 0, 
01322                                     sizeof(user_frame_buffer_draw_action));
01323                 mMutexClicked.lock();
01324                 clickedCode = CLICKED_UNKNOWN;
01325                 mMutexClicked.unlock();
01326                 
01327                 // Clean draw faces
01328                 mMutexObjects.lock();
01329                 if(gIsDrawing == false)
01330                 {
01331                     mMutexObjects.unlock();
01332                     gObjectDetects.clear();
01333                     gIsDrawing = true;
01334                     p_DrawObjects->signal_set(1);
01335                 }
01336                 else
01337                 {
01338                     mMutexObjects.unlock();
01339                 }
01340             }
01341         }
01342         else
01343         {
01344             mMutexObjects.unlock();
01345         }
01346         
01347         /* Reset flag */
01348         faces.clear();
01349         mMutexProcess.lock();
01350         gIsProcessing = false;
01351         mMutexProcess.unlock();
01352         
01353         /* Clean cache */
01354         dcache_clean(user_frame_buffer_draw_action, 
01355                                     sizeof(user_frame_buffer_draw_action));
01356     }
01357 }
01358 
01359 /* 2 functions for gesture recognition */
01360 int distanceP2P(Point2f  a, Point2f  b)
01361 {
01362     int d = (int)sqrt(fabs(pow(a.x - b.x, 2) + pow(a.y - b.y, 2)));
01363     return d;
01364 }
01365 
01366 float getAngle(Point  s, Point  f, Point  e){
01367     float l1 = distanceP2P(f, s);
01368     float l2 = distanceP2P(f, e);
01369     float dot = (s.x - f.x)*(e.x - f.x) + (s.y - f.y)*(e.y - f.y);
01370     float angle = acos(dot / (l1*l2));
01371     angle = angle * 180 / M_PI;
01372     return angle;
01373 }
01374 
01375 void drawButtonSampling(graphicFrameworkCanvas canvas,bool sampling)
01376 {
01377     // Clear 21 lines
01378     memset(user_frame_buffer_draw_action + (GESTURE_SAMPLING_BTN_Y - 1)*
01379         LCD_PIXEL_WIDTH*FRAME_BUFFER_BYTE_PER_PIXEL, 0, 
01380         21*LCD_PIXEL_WIDTH*FRAME_BUFFER_BYTE_PER_PIXEL);
01381     if(sampling == true) // Sampling, Clicking stop, draw sampling
01382     { 
01383         canvas.drawImage(my_img_sampling, GESTURE_SAMPLING_BTN_X, 
01384                             GESTURE_SAMPLING_BTN_Y);
01385     }
01386     else
01387     {
01388         canvas.drawImage(my_img_stop, GESTURE_SAMPLING_BTN_X, 
01389                             GESTURE_SAMPLING_BTN_Y);
01390     }
01391 }
01392 
01393 void gestureRegconition(void)
01394 {
01395     // Init draw
01396     graphicFrameworkCanvas myCanvas(user_frame_buffer_draw_action, 0x01E0,
01397                     0x0110, (uint8_t)DRAW_BUFFER_BYTE_PER_PIXEL, 
01398                     (uint8_t)DRAW_POINT,0x06);
01399 
01400     bool sampling = true;
01401     int kernelSize = 7;
01402     int thresValue = 100;
01403     int maxIndex = 0;
01404     double area = 0.0;
01405     unsigned long lArea = 0, maxArea = 0;
01406     int hullSize = 0;
01407     bool handSamp = true;
01408     bool isFinger = false;
01409     int oneFinger = 0;
01410     int countFinger = 0;
01411     Sampling handdist;
01412     Point2f  mPa;
01413     ConvexPoint checkPoint;
01414     
01415     Mat imgGray;
01416     Mat blurImg;
01417     Mat thresholdImg;
01418     vector<vector<Point> > contours;
01419     vector<mLine> lLines;
01420     vector<mCircle> lCircles;
01421     vector<Point> lMaxContour;
01422     
01423     myCanvas.drawImage(my_img_stop, GESTURE_SAMPLING_BTN_X, 
01424                                     GESTURE_SAMPLING_BTN_Y);
01425     mMutexClicked.lock();
01426     clickedCode = CLICKED_UNKNOWN;
01427     mMutexClicked.unlock();
01428     clearGestureResult(gGestureResult);
01429     while(1)
01430     {
01431         semProcessThread.wait();
01432         
01433         //Test
01434         /*char f_name[40];
01435         sprintf(f_name,"/SD/img_test%d.txt",count++);
01436         Mat res_tmp = _m_cvtRgb5652Rgb(my_frame,(int)LCD_PIXEL_WIDTH,
01437                                                 (int)LCD_PIXEL_HEIGHT,2);
01438         writeMatToTxt(res_tmp,f_name);
01439         mMutexProcess.lock();
01440         gIsProcessing = false;
01441         mMutexProcess.unlock();
01442         continue;     */                                        
01443         
01444         //end test
01445         
01446         if ( appMode != GUESTURE_RECOGNITION )
01447         {
01448             mMutexProcess.lock();
01449             gIsProcessing = false;
01450             mMutexProcess.unlock();
01451             memset(user_frame_buffer_draw_action, 0, 
01452                                     sizeof(user_frame_buffer_draw_action));   
01453             clearGestureResult(gGestureResult);  
01454             break;
01455         }
01456         
01457         //Draw button sampling
01458         mMutexClicked.lock();
01459         if (clickedCode == CLICKED_HAND_SAMPLING)
01460         {
01461             clickedCode = CLICKED_UNKNOWN;
01462             mMutexClicked.unlock();
01463             drawButtonSampling(myCanvas,sampling);
01464             sampling = !sampling;
01465         }
01466         else
01467         {
01468             mMutexClicked.unlock();
01469         }
01470 
01471         // Get frame camera
01472         {
01473             Mat res = _m_cvtRgb5652Rgb(my_frame,(int)LCD_PIXEL_WIDTH,
01474                                                 (int)LCD_PIXEL_HEIGHT,2);
01475             cvtColor(res,imgGray,COLOR_RGB2GRAY);
01476             res.release();
01477         }
01478         
01479         //Clear old data
01480         lLines.clear();
01481         lCircles.clear();
01482         lMaxContour.clear();
01483         
01484         // Start processing
01485         blur(imgGray,blurImg,Size(kernelSize,kernelSize));
01486         threshold(blurImg,thresholdImg,thresValue,255,CV_THRESH_BINARY);
01487 
01488         checkPoint.Pointstart.clear();
01489         checkPoint.Pointdepth.clear();
01490         checkPoint.Pointindex.clear();
01491         checkPoint.detecthand = 0;
01492         
01493         findContours(thresholdImg,contours,CV_RETR_EXTERNAL,
01494                                             CV_CHAIN_APPROX_SIMPLE,Point (0,0));
01495 
01496         if(contours.size() > 0)
01497         {
01498             //togle_led(LED_GREEN);
01499             maxIndex = 0;
01500             vector<vector<int> > hull(contours.size());
01501             vector<vector<Vec4i> > convDef(contours.size());
01502             vector<vector<Point> > hull_point(contours.size());
01503             vector<vector<Point> > detectPoint(contours.size());
01504             
01505             for(int i = 0;i < contours.size();i++)
01506             {
01507                 area = contourArea(contours[i]);
01508                 lArea = long(area);
01509                 if(lArea > maxArea)
01510                 {
01511                     hullSize++;
01512                     maxArea = lArea;
01513                     maxIndex = i;
01514                 }
01515             }
01516             
01517             if(maxArea > 50000)
01518             {
01519                 //togle_reset(LED_RED,LED_BLUE);
01520                 checkPoint.detecthand = 1;
01521                 convexHull(Mat(contours[maxIndex]),hull[maxIndex],false);
01522                 convexityDefects(contours[maxIndex],hull[maxIndex],convDef[maxIndex]);
01523             }
01524             
01525             for (int i = 0;i < convDef[maxIndex].size();i++)
01526             {
01527                 if(convDef[maxIndex][i][3] > 20*256)
01528                 {
01529                     int ind_0 = convDef[maxIndex][i][0];
01530                     int ind_1 = convDef[maxIndex][i][2];
01531                     checkPoint.Pointstart.push_back(contours[maxIndex][ind_0]);
01532                     checkPoint.Pointdepth.push_back(contours[maxIndex][ind_1]);
01533                     checkPoint.Pointindex.push_back(ind_1);
01534                 }
01535             }
01536 
01537             vector<Moments> mu(contours.size());
01538             vector<Point2d> mc(contours.size());    
01539             mu[maxIndex] = moments(contours[maxIndex],false);
01540             mc[maxIndex] = Point2f (mu[maxIndex].m10 / mu[maxIndex].m00,
01541                                    mu[maxIndex].m01 / mu[maxIndex].m00);
01542             mPa = mc[maxIndex];
01543 
01544             // Reset values
01545             lArea = 0;
01546             maxArea = 0;
01547             hullSize = 0;
01548             area = 0;
01549             
01550             
01551             // Draw contours
01552             Mat imgContour(LCD_PIXEL_HEIGHT,LCD_PIXEL_WIDTH,CV_8UC1,Scalar (0));
01553             drawContours(imgContour,contours,maxIndex,Scalar (255));
01554             for(int i=0;i<imgContour.rows;i++)
01555             {
01556                 for(int j=0;j<imgContour.cols;j++)
01557                 {
01558                     if(imgContour.at<uchar>(i,j) == 255)
01559                     {
01560                         lMaxContour.push_back(Point (j,i));
01561                     }
01562                 }
01563             }
01564             
01565             
01566         }// contours.size() > 0
01567         else
01568         {
01569             checkPoint.detecthand = 0;
01570         }
01571         
01572         if(sampling == true)
01573         {
01574             if (checkPoint.Pointstart.size() > 1)
01575             {
01576                 for(int i = 0;i < checkPoint.Pointstart.size() -1;i++)
01577                 {
01578                     float pAngle = getAngle(checkPoint.Pointstart[i],mPa,
01579                                                     checkPoint.Pointstart[i+1]);
01580                     float fAngle = getAngle(checkPoint.Pointstart[1],mPa,
01581                                                     checkPoint.Pointstart[i+1]);
01582     
01583                     if(pAngle < 90.00 && pAngle > 5.00 && fAngle < 180)
01584                     {
01585                         double pFdist = distanceP2P(mPa,
01586                                                     checkPoint.Pointstart[i]);
01587                         double pLdist = distanceP2P(mPa,
01588                                                     checkPoint.Pointdepth[i]);
01589                         double _Pmax = handdist.hand_max;
01590                         double _Pmin = handdist.hand_min;
01591                         if (pFdist > pLdist)
01592                         {
01593                             if (pFdist > _Pmax)
01594                             {
01595                                 handdist.hand_max = pFdist;
01596                             }
01597                             if (pLdist < _Pmin)
01598                             {
01599                                 handdist.hand_min = pLdist;
01600                             }
01601                         }
01602                         else
01603                         {
01604                             if (pLdist > _Pmin)
01605                             {
01606                                 handdist.hand_max = pLdist;
01607                             }
01608                             if (pFdist < _Pmin)
01609                             {
01610                                 handdist.hand_min = pFdist;
01611                             }
01612                         }
01613                     }
01614                 }
01615             }
01616         }//sampling == true
01617         else
01618         {
01619             if(checkPoint.detecthand == 1)
01620             {
01621                 if (checkPoint.Pointstart.size() > 1)
01622                 {
01623                     for(int i = 0;i < checkPoint.Pointstart.size() -1;i++)
01624                     {
01625                         float pAngle = getAngle(checkPoint.Pointstart[i],mPa,
01626                                                     checkPoint.Pointstart[i+1]);
01627                         float fAngle = getAngle(checkPoint.Pointstart[1],mPa,
01628                                                     checkPoint.Pointstart[i+1]);
01629 
01630                         // Draw line
01631                         mLine aLine;
01632                         aLine.x1 = (int)checkPoint.Pointstart[i].x;
01633                         aLine.y1 = (int)checkPoint.Pointstart[i].y;
01634                         aLine.x2 = (int)mPa.x;
01635                         aLine.y2 = (int)mPa.y;
01636                         aLine.color[0] = 0x00;//Color red
01637                         aLine.color[1] = 0xFF;
01638                         lLines.push_back(aLine);
01639                         //line(showRes,checkPoint.Pointstart[i],mPa,
01640 //                                                            Scalar(255,255,0));
01641                         //Draw circle
01642                         mCircle cir;
01643                         cir.x = (int)checkPoint.Pointstart[i].x;
01644                         cir.y = (int)checkPoint.Pointstart[i].y;
01645                         cir.radius = 10;
01646                         cir.color[0] = 0xF0;
01647                         cir.color[1] = 0xF0;//Color green
01648                         lCircles.push_back(cir);
01649                         
01650                         
01651                         //circle(showRes,checkPoint.Pointstart[i],10,
01652 //                                                            Scalar(0,255,0));
01653     
01654                         if(pAngle < 90.00 && pAngle > 5.00 && fAngle < 180)
01655                         {
01656                             double pFdist = distanceP2P(mPa,
01657                                                     checkPoint.Pointstart[i]);
01658                             if(pFdist > (handdist.hand_min + 110) && 
01659                                 pFdist < (handdist.hand_max + 40))
01660                             {
01661                                 isFinger = true;
01662                                 //line(showRes,checkPoint.Pointstart[i],mPa,Scalar(255,255,255));
01663                                 aLine.x1 = (int)checkPoint.Pointstart[i].x;
01664                                 aLine.y1 = (int)checkPoint.Pointstart[i].y;
01665                                 aLine.x2 = (int)mPa.x;
01666                                 aLine.y2 = (int)mPa.y;// Keep color red
01667                                 lLines.push_back(aLine);
01668                                 
01669                                 oneFinger++;
01670                             }
01671                             else
01672                             {
01673                                 isFinger = false;
01674                             }
01675     
01676                             if(isFinger == true)
01677                             {
01678                                 //circle(showRes,mPa,handdist.hand_min,Scalar(255,0,0));
01679                                 cir.x = (int)mPa.x;
01680                                 cir.y = (int)mPa.y;
01681                                 cir.radius = (int)handdist.hand_min;
01682                                 lCircles.push_back(cir);//color green
01683                                 
01684                                 //circle(showRes,mPa,handdist.hand_min + 110,Scalar(255,0,0));
01685                                 cir.radius = (int)handdist.hand_min + 110;
01686                                 lCircles.push_back(cir);//color green
01687                                 
01688                                 double pLdist = distanceP2P(mPa,checkPoint.Pointdepth[i]);
01689                                 if(pLdist > handdist.hand_min - 5)
01690                                 {
01691                                     countFinger++;
01692                                     //circle(showRes,contours[maxIndex][checkPoint.Pointindex[i]],2,Scalar(0,255,255));
01693                                     cir.x = (int)contours[maxIndex][checkPoint.Pointindex[i]].x;
01694                                     cir.y = (int)contours[maxIndex][checkPoint.Pointindex[i]].y;
01695                                     cir.radius = 2;
01696                                     lCircles.push_back(cir);//color green
01697                                 }
01698                             }
01699                         }
01700                     }// for
01701                     if(isFinger == false)
01702                     {
01703                         for(int i = 0; i < checkPoint.Pointstart.size() -1;i++)
01704                         {
01705                             double pLdist = distanceP2P(mPa,
01706                                                     checkPoint.Pointdepth[i]);
01707                             if (pLdist > (handdist.hand_min - 5))
01708                             {
01709                                 countFinger = 0;
01710                                 isFinger = true;
01711                             }
01712                         }
01713                     }
01714                 }//checkPoint.Pointstart.size() > 1
01715             }//checkPoint.detecthand == 1
01716         }
01717         
01718         // Draw
01719         mMutexObjects.lock();
01720         if(gIsDrawing == false)
01721         {
01722             mMutexObjects.unlock();
01723             
01724             // Assign data
01725             gGestureResult.circles = lCircles;
01726             gGestureResult.lines = lLines;
01727             gGestureResult.contour = lMaxContour;
01728             
01729             gIsDrawing = true;
01730             p_DrawObjects->signal_set(1);
01731         }
01732         else
01733         {
01734             mMutexObjects.unlock();
01735         }
01736         
01737         mMutexProcess.lock();
01738         gIsProcessing = false;
01739         mMutexProcess.unlock();
01740 
01741         /* Clean cache */
01742         dcache_clean(user_frame_buffer_draw_action, 
01743                                     sizeof(user_frame_buffer_draw_action));
01744     }
01745     
01746 }
01747 
01748 /****** main image process here******/
01749 int main(void) {
01750     /* Init SD card*/
01751     myStorage = new cStorage(SDCARD_NAME);
01752     if( initSdCard() == false)
01753     {
01754         while(1);
01755     }
01756     togle_reset(LED_RED,LED_BLUE);
01757     
01758     /* Initialization of LCD */
01759     Init_LCD_Display();    /* When using LCD, please call before than Init_Video(). */
01760 
01761     /* Initialization of Video */
01762     Init_Video();
01763     
01764     /* Start Video and Lcd processing */
01765     p_VideoLcdTask = new Thread();
01766     p_VideoLcdTask->start(video_lcd_task);
01767     
01768     p_Touch = new Thread();
01769     p_Touch->start(touch_task);
01770     
01771     /* Start image processor*/
01772     p_DrawObjects = new Thread();
01773     p_DrawObjects->signal_set(0);
01774     p_DrawObjects->start(img_draw_objects);
01775     
01776     initDrawAction();
01777     
01778     while(1)
01779     {
01780         switch(appMode)
01781         {
01782             case FACE_DETECTION:
01783             {
01784                 faceDectectionApp();
01785                 break;
01786             }
01787             case MOTION_DETECTION:
01788             {
01789                 motionDetectionApp();
01790                 break;
01791             }
01792             case FACE_RECOGNITION:
01793             {
01794                 faceRecognitionApp();
01795                 break;
01796             }
01797             case GUESTURE_RECOGNITION:
01798             {
01799                 gestureRegconition();
01800                 break;
01801             }
01802             default:
01803             {
01804                 wait(0.5);
01805                 break;
01806             }
01807         }
01808     }
01809     return 1;
01810 }