Mar. 14. 2018

Dependencies:   GraphicsFramework GR-PEACH_video LCD_shield_config AsciiFont R_BSP USBHost_custom

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers recognition_proc.cpp Source File

recognition_proc.cpp

00001 #include "mbed.h"
00002 #include "DisplayBace.h"
00003 #include "rtos.h"
00004 #include "AsciiFont.h"
00005 #include "USBHostSerial.h"
00006 #include "LCD_shield_config_4_3inch.h"
00007 #include "recognition_proc.h"
00008 #include "STBWrap.h"
00009 
00010 #define UART_SETTING_TIMEOUT              1000            /* HVC setting command signal timeout period */
00011 #define UART_REGIST_EXECUTE_TIMEOUT       7000            /* HVC registration command signal timeout period */
00012 #define UART_EXECUTE_TIMEOUT             10000            /* HVC execute command signal timeout period */
00013 
00014 #define SENSOR_ROLL_ANGLE_DEFAULT            0            /* Camera angle setting */
00015 #define USER_ID_NUM_MAX                     10
00016 
00017 #define ERROR_02                         "Error: Number of detected faces is 2 or more"
00018 
00019 #define DISP_PIXEL_WIDTH                 (320)
00020 #define DISP_PIXEL_HEIGHT                (240)
00021 
00022 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128
00023     in accordance with the frame buffer burst transfer mode. */
00024 /* FRAME BUFFER Parameter GRAPHICS_LAYER_0 */
00025 #define FRAME_BUFFER_BYTE_PER_PIXEL   (2u)
00026 #define FRAME_BUFFER_STRIDE           (((DISP_PIXEL_WIDTH * FRAME_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
00027 
00028 /* RESULT BUFFER Parameter GRAPHICS_LAYER_1 */
00029 #define RESULT_BUFFER_BYTE_PER_PIXEL  (2u)
00030 #define RESULT_BUFFER_STRIDE          (((DISP_PIXEL_WIDTH * RESULT_BUFFER_BYTE_PER_PIXEL) + 31u) & ~31u)
00031 
00032 static bool  registrationr_req = false;
00033 static bool  setting_req = false;
00034 static recognition_setting_t setting = {
00035     0,
00036     { BODY_THRESHOLD_DEFAULT, HAND_THRESHOLD_DEFAULT, FACE_THRESHOLD_DEFAULT, REC_THRESHOLD_DEFAULT},
00037     { BODY_SIZE_RANGE_MIN_DEFAULT, BODY_SIZE_RANGE_MAX_DEFAULT, HAND_SIZE_RANGE_MIN_DEFAULT,
00038       HAND_SIZE_RANGE_MAX_DEFAULT, FACE_SIZE_RANGE_MIN_DEFAULT, FACE_SIZE_RANGE_MAX_DEFAULT},
00039     FACE_POSE_DEFAULT,
00040     FACE_ANGLE_DEFAULT
00041 };
00042 static USBHostSerial serial;
00043 static InterruptIn button(USER_BUTTON0);
00044 
00045 #if defined(__ICCARM__)
00046 /* 32 bytes aligned */
00047 #pragma data_alignment=32
00048 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * DISP_PIXEL_HEIGHT]@ ".mirrorram";
00049 #pragma data_alignment=32
00050 static uint8_t user_frame_buffer_result[RESULT_BUFFER_STRIDE * DISP_PIXEL_HEIGHT]@ ".mirrorram";
00051 #else
00052 /* 32 bytes aligned */
00053 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * DISP_PIXEL_HEIGHT]__attribute((section("NC_BSS"),aligned(32)));
00054 static uint8_t user_frame_buffer_result[RESULT_BUFFER_STRIDE * LCD_PIXEL_HEIGHT]__attribute((section("NC_BSS"),aligned(32)));
00055 #endif
00056 
00057 static AsciiFont ascii_font(user_frame_buffer_result, DISP_PIXEL_WIDTH, LCD_PIXEL_HEIGHT,
00058                             RESULT_BUFFER_STRIDE, RESULT_BUFFER_BYTE_PER_PIXEL, 0x00000090);
00059 static INT32 imageNo_setting = HVC_EXECUTE_IMAGE_QVGA_HALF;
00060 static int str_draw_x = 0;
00061 static int str_draw_y = 0;
00062 
00063 /****** Image Recognition ******/
00064 extern "C" int UART_SendData(int inDataSize, UINT8 *inData) {
00065     return serial.writeBuf((char *)inData, inDataSize);
00066 }
00067 
00068 extern "C" int UART_ReceiveData(int inTimeOutTime, int inDataSize, UINT8 *outResult) {
00069     return serial.readBuf((char *)outResult, inDataSize, inTimeOutTime);
00070 }
00071 
00072 void SetRegistrationrReq(void) {
00073     registrationr_req = true;
00074 }
00075 
00076 void SetSettingReq(void) {
00077     setting_req = true;
00078 }
00079 
00080 recognition_setting_t * GetRecognitionSettingPointer(void) {
00081     return &setting;
00082 }
00083 
00084 static void EraseImage(void) {
00085     uint32_t i = 0;
00086     while (i < sizeof(user_frame_buffer0)) {
00087         user_frame_buffer0[i++] = 0x10;
00088         user_frame_buffer0[i++] = 0x80;
00089     }
00090 }
00091 
00092 static void DrawImage(int x, int y, int nWidth, int nHeight, UINT8 *unImageBuffer, int magnification) {
00093     int idx_base;
00094     int idx_w = 0;
00095     int wk_tmp = 0;
00096     int i;
00097     int j;
00098     int k;
00099     int idx_r = 0;
00100 
00101     if (magnification <= 0) {
00102         return;
00103     }
00104 
00105     idx_base = (x + (DISP_PIXEL_WIDTH * y)) * RESULT_BUFFER_BYTE_PER_PIXEL;
00106 
00107     for (i = 0; i < nHeight; i++) {
00108         idx_w = idx_base + (DISP_PIXEL_WIDTH * RESULT_BUFFER_BYTE_PER_PIXEL * i) * magnification;
00109         wk_tmp = idx_w;
00110         for (j = 0; j < nWidth; j++) {
00111             for (k = 0; k < magnification; k++) {
00112                 user_frame_buffer0[idx_w] = unImageBuffer[idx_r];
00113                 idx_w += 2;
00114             }
00115             idx_r++;
00116         }
00117         for (k = 1; k < magnification; k++) {
00118             memcpy(&user_frame_buffer0[wk_tmp + (DISP_PIXEL_WIDTH * RESULT_BUFFER_BYTE_PER_PIXEL * k)], &user_frame_buffer0[wk_tmp], idx_w - wk_tmp);
00119         }
00120     }
00121 }
00122 
00123 static void DrawSquare(int x, int y, int size, uint32_t const colour) {
00124     int wk_x;
00125     int wk_y;
00126     int wk_w = 0;
00127     int wk_h = 0;
00128     int idx_base;
00129     int wk_idx;
00130     int i;
00131     int j;
00132     uint8_t coller_pix[RESULT_BUFFER_BYTE_PER_PIXEL];  /* ARGB4444 */
00133     bool l_draw = true;
00134     bool r_draw = true;
00135     bool t_draw = true;
00136     bool b_draw = true;
00137 
00138     if ((x - (size / 2)) < 0) {
00139         l_draw = false;
00140         wk_w += x;
00141         wk_x = 0;
00142     } else {
00143         wk_w += (size / 2);
00144         wk_x = x - (size / 2);
00145     }
00146 
00147     if ((x + (size / 2)) >= 1600) {
00148         r_draw = false;
00149         wk_w += (1600 - x);
00150     } else {
00151         wk_w += (size / 2);
00152     }
00153 
00154     if ((y - (size / 2)) < 0) {
00155         t_draw = false;
00156         wk_h += y;
00157         wk_y = 0;
00158     } else {
00159         wk_h += (size / 2);
00160         wk_y = y - (size / 2);
00161     }
00162 
00163     if ((y + (size / 2)) >= 1200) {
00164         b_draw = false;
00165         wk_h += (1200 - y);
00166     } else {
00167         wk_h += (size / 2);
00168     }
00169 
00170     wk_x = wk_x / 5;
00171     wk_y = wk_y / 5;
00172     wk_w = wk_w / 5;
00173     wk_h = wk_h / 5;
00174 
00175     if ((colour == 0x0000f0f0) || (colour == 0x0000fff4)) {
00176         str_draw_x = wk_x;
00177         str_draw_y = wk_y + wk_h + 1;
00178     }
00179 
00180     idx_base = (wk_x + (DISP_PIXEL_WIDTH * wk_y)) * RESULT_BUFFER_BYTE_PER_PIXEL;
00181 
00182     /* Select color */
00183     coller_pix[0] = (colour >> 8) & 0xff;  /* 4:Green 4:Blue */
00184     coller_pix[1] = colour & 0xff;         /* 4:Alpha 4:Red  */
00185 
00186     /* top */
00187     if (t_draw) {
00188         wk_idx = idx_base;
00189         for (j = 0; j < wk_w; j++) {
00190             user_frame_buffer_result[wk_idx++] = coller_pix[0];
00191             user_frame_buffer_result[wk_idx++] = coller_pix[1];
00192         }
00193     }
00194 
00195     /* middle */
00196     for (i = 1; i < (wk_h - 1); i++) {
00197         wk_idx = idx_base + (DISP_PIXEL_WIDTH * RESULT_BUFFER_BYTE_PER_PIXEL * i);
00198         if (l_draw) {
00199             user_frame_buffer_result[wk_idx + 0] = coller_pix[0];
00200             user_frame_buffer_result[wk_idx + 1] = coller_pix[1];
00201         }
00202         wk_idx += (wk_w - 1) * 2;
00203         if (r_draw) {
00204             user_frame_buffer_result[wk_idx + 0] = coller_pix[0];
00205             user_frame_buffer_result[wk_idx + 1] = coller_pix[1];
00206         }
00207     }
00208 
00209     /* bottom */
00210     if (b_draw) {
00211         wk_idx = idx_base + (DISP_PIXEL_WIDTH * RESULT_BUFFER_BYTE_PER_PIXEL * (wk_h - 1));
00212         for (j = 0; j < wk_w; j++) {
00213             user_frame_buffer_result[wk_idx++] = coller_pix[0];
00214             user_frame_buffer_result[wk_idx++] = coller_pix[1];
00215         }
00216     }
00217 }
00218 
00219 static void DrawString(const char * str, uint32_t const colour) {
00220     ascii_font.Erase(0x00000090, str_draw_x, str_draw_y,
00221                      (AsciiFont::CHAR_PIX_WIDTH * strlen(str) + 2),
00222                      (AsciiFont::CHAR_PIX_HEIGHT + 2));
00223     ascii_font.DrawStr(str, str_draw_x + 1, str_draw_y + 1, colour, 1);
00224     str_draw_y += AsciiFont::CHAR_PIX_HEIGHT + 1;
00225 }
00226 
00227 static void button_fall(void) {
00228     if (imageNo_setting == HVC_EXECUTE_IMAGE_NONE) {
00229         imageNo_setting = HVC_EXECUTE_IMAGE_QVGA_HALF;
00230     } else if (imageNo_setting == HVC_EXECUTE_IMAGE_QVGA_HALF) {
00231         imageNo_setting = HVC_EXECUTE_IMAGE_QVGA;
00232     } else {
00233         imageNo_setting = HVC_EXECUTE_IMAGE_NONE;
00234     }
00235 }
00236 
00237 void init_recognition_layers(DisplayBase * p_display) {
00238     DisplayBase::rect_t rect;
00239 
00240     /* The layer by which the image is drawn */
00241     rect.vs = 0;
00242     rect.vw = DISP_PIXEL_HEIGHT;
00243     rect.hs = 0;
00244     rect.hw = DISP_PIXEL_WIDTH;
00245     p_display->Graphics_Read_Setting(
00246         DisplayBase::GRAPHICS_LAYER_0,
00247         (void *)user_frame_buffer0,
00248         FRAME_BUFFER_STRIDE,
00249         DisplayBase::GRAPHICS_FORMAT_YCBCR422,
00250         DisplayBase::WR_RD_WRSWA_32_16BIT,
00251         &rect
00252     );
00253     p_display->Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
00254 
00255     /* The layer by which the image recognition is drawn */
00256     rect.vs = 0;
00257     rect.vw = LCD_PIXEL_HEIGHT;
00258     rect.hs = 0;
00259     rect.hw = DISP_PIXEL_WIDTH;
00260     p_display->Graphics_Read_Setting(
00261         DisplayBase::GRAPHICS_LAYER_1,
00262         (void *)user_frame_buffer_result,
00263         RESULT_BUFFER_STRIDE,
00264         DisplayBase::GRAPHICS_FORMAT_ARGB4444,
00265         DisplayBase::WR_RD_WRSWA_32_16BIT,
00266         &rect
00267     );
00268     p_display->Graphics_Start(DisplayBase::GRAPHICS_LAYER_1);
00269 }
00270 
00271 void recognition_task(DisplayBase * p_display) {
00272     INT32 ret = 0;
00273     UINT8 status;
00274     HVC_VERSION version;
00275     HVC_RESULT *pHVCResult = NULL;
00276 
00277     int nSTBFaceCount;
00278     STB_FACE *pSTBFaceResult;
00279     int nSTBBodyCount;
00280     STB_BODY *pSTBBodyResult;
00281     int nIndex;
00282 
00283     HVC_IMAGE *pImage = NULL;
00284     INT32 execFlag;
00285     INT32 imageNo;
00286     INT32 userID;
00287     INT32 next_userID;
00288     INT32 dataID;
00289     const char *pExStr[] = {"?", "Neutral", "Happiness", "Surprise", "Anger", "Sadness"};
00290     uint32_t i;
00291     char Str_disp[32];
00292     Timer resp_time;
00293     INT32 TrackingID;
00294 
00295     /* Register the button */
00296     button.fall(&button_fall);
00297 
00298     /* Initializing Recognition layers */
00299     EraseImage();
00300     memset(user_frame_buffer_result, 0, sizeof(user_frame_buffer_result));
00301     init_recognition_layers(p_display);
00302 
00303     /* Result Structure Allocation */
00304     pHVCResult = (HVC_RESULT *)malloc(sizeof(HVC_RESULT));
00305     if (pHVCResult == NULL) {
00306         printf("Memory Allocation Error : %08x\n", sizeof(HVC_RESULT));
00307         mbed_die();
00308     }
00309 
00310     /* STB Initialize */
00311     ret = STB_Init(STB_FUNC_BD | STB_FUNC_DT | STB_FUNC_PT | STB_FUNC_AG | STB_FUNC_GN);
00312     if (ret != 0) {
00313         printf("STB_Init Error : %d\n", ret);
00314         mbed_die();
00315     }
00316 
00317     /* Image Structure allocation */
00318     pImage = (HVC_IMAGE *)malloc(sizeof(HVC_IMAGE));
00319     if (pImage == NULL) {
00320         printf("Memory Allocation Error : %08x\n", sizeof(HVC_RESULT));
00321         mbed_die();
00322     }
00323 
00324     while (1) {
00325         /* try to connect a serial device */
00326         while (!serial.connect()) {
00327             Thread::wait(500);
00328         }
00329         serial.baud(921600);
00330         setting_req = true;
00331 
00332         do {
00333             /* Initializing variables */
00334             next_userID = 0;
00335             dataID = 0;
00336 
00337             /* Get Model and Version */
00338             ret = HVC_GetVersion(UART_SETTING_TIMEOUT, &version, &status);
00339             if ((ret != 0) || (status != 0)) {
00340                 break;
00341             }
00342 
00343             while (1) {
00344                 if (!serial.connected()) {
00345                     break;
00346                 }
00347 
00348                 /* Execute Setting */
00349                 if (setting_req) {
00350                     setting_req = false;
00351                     /* Set Camera Angle */
00352                     ret = HVC_SetCameraAngle(UART_SETTING_TIMEOUT, SENSOR_ROLL_ANGLE_DEFAULT, &status);
00353                     if ((ret != 0) || (status != 0)) {
00354                         break;
00355                     }
00356                     /* Set Threshold Values */
00357                     ret = HVC_SetThreshold(UART_SETTING_TIMEOUT, &setting.threshold, &status);
00358                     if ((ret != 0) || (status != 0)) {
00359                         break;
00360                     }
00361                     ret = HVC_GetThreshold(UART_SETTING_TIMEOUT, &setting.threshold, &status);
00362                     if ((ret != 0) || (status != 0)) {
00363                         break;
00364                     }
00365                     /* Set Detection Size */
00366                     ret = HVC_SetSizeRange(UART_SETTING_TIMEOUT, &setting.sizeRange, &status);
00367                     if ((ret != 0) || (status != 0)) {
00368                         break;
00369                     }
00370                     ret = HVC_GetSizeRange(UART_SETTING_TIMEOUT, &setting.sizeRange, &status);
00371                     if ((ret != 0) || (status != 0)) {
00372                         break;
00373                     }
00374                     /* Set Face Angle */
00375                     ret = HVC_SetFaceDetectionAngle(UART_SETTING_TIMEOUT, setting.pose, setting.angle, &status);
00376                     if ((ret != 0) || (status != 0)) {
00377                         break;
00378                     }
00379                     ret = HVC_GetFaceDetectionAngle(UART_SETTING_TIMEOUT, &setting.pose, &setting.angle, &status);
00380                     if ((ret != 0) || (status != 0)) {
00381                         break;
00382                     }
00383 
00384                     /* Set STB Parameters */
00385                     ret = STB_SetTrParam(STB_RETRYCOUNT_DEFAULT, STB_POSSTEADINESS_DEFAULT, STB_SIZESTEADINESS_DEFAULT);
00386                     if (ret != 0) {
00387                         break;
00388                     }
00389                     ret = STB_SetPeParam(STB_PE_THRESHOLD_DEFAULT, STB_PE_ANGLEUDMIN_DEFAULT, STB_PE_ANGLEUDMAX_DEFAULT,
00390                                          STB_PE_ANGLELRMIN_DEFAULT, STB_PE_ANGLELRMAX_DEFAULT, STB_PE_FRAME_DEFAULT);
00391                     if (ret != 0) {
00392                         break;
00393                     }
00394                 }
00395 
00396                 /* Execute Registration */
00397                 if (registrationr_req) {
00398                     int wk_width;
00399 
00400                     if ((pHVCResult->fdResult.num == 1) && (pHVCResult->fdResult.fcResult[0].recognitionResult.uid >= 0)) {
00401                         userID = pHVCResult->fdResult.fcResult[0].recognitionResult.uid;
00402                     } else {
00403                         userID = next_userID;
00404                     }
00405                     ret = HVC_Registration(UART_REGIST_EXECUTE_TIMEOUT, userID, dataID, pImage, &status);
00406                     if ((ret == 0) && (status == 0)) {
00407                         if (userID == next_userID) {
00408                             next_userID++;
00409                             if (next_userID >= USER_ID_NUM_MAX) {
00410                                 next_userID = 0;
00411                             }
00412                         }
00413                         memset(user_frame_buffer_result, 0, sizeof(user_frame_buffer_result));
00414                         DrawImage(128, 88, pImage->width, pImage->height, pImage->image, 1);
00415                         memset(Str_disp, 0, sizeof(Str_disp));
00416                         sprintf(Str_disp, "USER%03d", userID + 1);
00417                         wk_width = (AsciiFont::CHAR_PIX_WIDTH * strlen(Str_disp)) + 2;
00418                         ascii_font.Erase(0x00000090, (DISP_PIXEL_WIDTH - wk_width) / 2, 153, wk_width, (AsciiFont::CHAR_PIX_HEIGHT + 2));
00419                         ascii_font.DrawStr(Str_disp, (DISP_PIXEL_WIDTH - wk_width) / 2 + 1, 154, 0x0000ffff, 1);
00420                         Thread::wait(1200);
00421                     } else {
00422                         if (status == 0x02) {
00423                             wk_width = (AsciiFont::CHAR_PIX_WIDTH * (sizeof(ERROR_02) - 1)) + 4;
00424                             ascii_font.Erase(0x00000090, (DISP_PIXEL_WIDTH - wk_width) / 2, 120, wk_width, (AsciiFont::CHAR_PIX_HEIGHT + 3));
00425                             ascii_font.DrawStr(ERROR_02, (DISP_PIXEL_WIDTH - wk_width) / 2 + 2, 121, 0x0000ffff, 1);
00426                             Thread::wait(1500);
00427                         }
00428                     }
00429                     registrationr_req = false;
00430                 }
00431 
00432                 /* Execute Detection */
00433                 execFlag = setting.execFlag;
00434                 if ((execFlag & HVC_ACTIV_FACE_DETECTION) == 0) {
00435                     execFlag &= ~(HVC_ACTIV_AGE_ESTIMATION | HVC_ACTIV_GENDER_ESTIMATION | HVC_ACTIV_EXPRESSION_ESTIMATION);
00436                 }
00437                 if (execFlag != 0) { // for STB
00438                     execFlag |= HVC_ACTIV_FACE_DIRECTION;
00439                 }
00440                 imageNo = imageNo_setting;
00441                 resp_time.reset();
00442                 resp_time.start();
00443                 ret = HVC_ExecuteEx(UART_EXECUTE_TIMEOUT, execFlag, imageNo, pHVCResult, &status);
00444                 resp_time.stop();
00445 
00446                 /* STB */
00447                 if (STB_Exec(pHVCResult->executedFunc, pHVCResult, &nSTBFaceCount, &pSTBFaceResult, &nSTBBodyCount, &pSTBBodyResult) == 0) {
00448                     for ( i = 0; i < nSTBBodyCount; i++ )
00449                     {
00450                         if ( pHVCResult->bdResult.num <= i ) break;
00451 
00452                         nIndex = pSTBBodyResult[i].nDetectID;
00453                         if (nIndex >= 0) {
00454                             pHVCResult->bdResult.bdResult[nIndex].posX = (short)pSTBBodyResult[i].center.x;
00455                             pHVCResult->bdResult.bdResult[nIndex].posY = (short)pSTBBodyResult[i].center.y;
00456                             pHVCResult->bdResult.bdResult[nIndex].size = pSTBBodyResult[i].nSize;
00457                         }
00458                     }
00459                     for (i = 0; i < nSTBFaceCount; i++)
00460                     {
00461                         if (pHVCResult->fdResult.num <= i) break;
00462 
00463                         nIndex = pSTBFaceResult[i].nDetectID;
00464                         if (nIndex >= 0) {
00465                             pHVCResult->fdResult.fcResult[nIndex].dtResult.posX = (short)pSTBFaceResult[i].center.x;
00466                             pHVCResult->fdResult.fcResult[nIndex].dtResult.posY = (short)pSTBFaceResult[i].center.y;
00467                             pHVCResult->fdResult.fcResult[nIndex].dtResult.size = pSTBFaceResult[i].nSize;
00468 
00469                             if (pHVCResult->executedFunc & HVC_ACTIV_AGE_ESTIMATION) {
00470                                 pHVCResult->fdResult.fcResult[nIndex].ageResult.confidence += 10000; // During
00471                                 if (pSTBFaceResult[i].age.status >= STB_STATUS_COMPLETE) {
00472                                     pHVCResult->fdResult.fcResult[nIndex].ageResult.age = pSTBFaceResult[i].age.value;
00473                                     pHVCResult->fdResult.fcResult[nIndex].ageResult.confidence += 10000; // Complete
00474                                 }
00475                             }
00476                             if (pHVCResult->executedFunc & HVC_ACTIV_GENDER_ESTIMATION) {
00477                                 pHVCResult->fdResult.fcResult[nIndex].genderResult.confidence += 10000; // During
00478                                 if (pSTBFaceResult[i].gender.status >= STB_STATUS_COMPLETE) {
00479                                     pHVCResult->fdResult.fcResult[nIndex].genderResult.gender = pSTBFaceResult[i].gender.value;
00480                                     pHVCResult->fdResult.fcResult[nIndex].genderResult.confidence += 10000; // Complete
00481                                 }
00482                             }
00483                         }
00484                     }
00485                 }
00486 
00487                 if ((ret == 0) && (status == 0)) {
00488                     if (imageNo == HVC_EXECUTE_IMAGE_QVGA_HALF) {
00489                         DrawImage(0, 0, pHVCResult->image.width, pHVCResult->image.height, pHVCResult->image.image, 2);
00490                     } else if (imageNo == HVC_EXECUTE_IMAGE_QVGA) {
00491                         DrawImage(0, 0, pHVCResult->image.width, pHVCResult->image.height, pHVCResult->image.image, 1);
00492                     } else {
00493                         EraseImage();
00494                     }
00495                     memset(user_frame_buffer_result, 0, sizeof(user_frame_buffer_result));
00496                     if (pHVCResult->executedFunc & HVC_ACTIV_BODY_DETECTION) {
00497                         /* Body Detection result */
00498                         for (i = 0; i < pHVCResult->bdResult.num; i++) {
00499                             DrawSquare(pHVCResult->bdResult.bdResult[i].posX, 
00500                                        pHVCResult->bdResult.bdResult[i].posY,
00501                                        pHVCResult->bdResult.bdResult[i].size,
00502                                        0x000000ff);
00503                         }
00504                     }
00505 
00506                     /* Face Detection result */
00507                     if (pHVCResult->executedFunc &
00508                             (HVC_ACTIV_FACE_DETECTION | HVC_ACTIV_FACE_DIRECTION |
00509                              HVC_ACTIV_AGE_ESTIMATION | HVC_ACTIV_GENDER_ESTIMATION |
00510                              HVC_ACTIV_GAZE_ESTIMATION | HVC_ACTIV_BLINK_ESTIMATION |
00511                              HVC_ACTIV_EXPRESSION_ESTIMATION | HVC_ACTIV_FACE_RECOGNITION)){
00512                         for (i = 0; i < pHVCResult->fdResult.num; i++) {
00513                             if (pHVCResult->executedFunc & HVC_ACTIV_FACE_DETECTION) {
00514                                 uint32_t detection_colour = 0x0000f0f0; /* green */
00515 
00516                                 if (pHVCResult->executedFunc & HVC_ACTIV_FACE_RECOGNITION) {
00517                                     if (pHVCResult->fdResult.fcResult[i].recognitionResult.uid >= 0) {
00518                                         detection_colour = 0x0000fff4; /* blue */
00519                                     }
00520                                 }
00521                                 /* Detection */
00522                                 DrawSquare(pHVCResult->fdResult.fcResult[i].dtResult.posX,
00523                                            pHVCResult->fdResult.fcResult[i].dtResult.posY,
00524                                            pHVCResult->fdResult.fcResult[i].dtResult.size,
00525                                            detection_colour);
00526                             }
00527                             TrackingID = 0;
00528                             for (int j = 0; j < nSTBFaceCount; j++)
00529                             {
00530                                 if (pSTBFaceResult[j].nDetectID == i) {
00531                                     TrackingID = pSTBFaceResult[j].nTrackingID;
00532                                     break;
00533                                 }
00534                             }
00535                             memset(Str_disp, 0, sizeof(Str_disp));
00536                             if (pHVCResult->executedFunc & HVC_ACTIV_FACE_RECOGNITION) {
00537                                 /* Recognition */
00538                                 if (pHVCResult->fdResult.fcResult[i].recognitionResult.uid < 0) {
00539                                     sprintf(Str_disp, "ID:%d", TrackingID);
00540                                 } else {
00541                                     sprintf(Str_disp, "USER%03d", pHVCResult->fdResult.fcResult[i].recognitionResult.uid + 1);
00542                                 }
00543                             } else {
00544                                 sprintf(Str_disp, "ID:%d", TrackingID);
00545                             }
00546                             DrawString(Str_disp, 0x0000f0ff);
00547                             if (pHVCResult->executedFunc & HVC_ACTIV_AGE_ESTIMATION) {
00548                                 /* Age */
00549                                 if (-128 != pHVCResult->fdResult.fcResult[i].ageResult.age) {
00550                                     memset(Str_disp, 0, sizeof(Str_disp));
00551                                     sprintf(Str_disp, "Age:%d", pHVCResult->fdResult.fcResult[i].ageResult.age);
00552                                     if (pHVCResult->fdResult.fcResult[i].ageResult.confidence < 20000) {
00553                                         strcat(Str_disp, " (?)");
00554                                     }
00555                                     DrawString(Str_disp, 0x0000f0ff);
00556                                 }
00557                             }
00558                             if (pHVCResult->executedFunc & HVC_ACTIV_GENDER_ESTIMATION) {
00559                                 /* Gender */
00560                                 if (-128 != pHVCResult->fdResult.fcResult[i].genderResult.gender) {
00561                                     uint32_t wk_color;
00562                                     memset(Str_disp, 0, sizeof(Str_disp));
00563                                     if (1 == pHVCResult->fdResult.fcResult[i].genderResult.gender) {
00564                                         sprintf(Str_disp, "Male");
00565                                         wk_color = 0x0000fff4;
00566                                     } else {
00567                                         sprintf(Str_disp, "Female");
00568                                         wk_color = 0x00006dff;
00569                                     }
00570                                     if ( pHVCResult->fdResult.fcResult[i].genderResult.confidence < 20000 ) {
00571                                         strcat(Str_disp, " (?)");
00572                                     }
00573                                     DrawString(Str_disp, wk_color);
00574                                 }
00575                             }
00576                             if (pHVCResult->executedFunc & HVC_ACTIV_EXPRESSION_ESTIMATION) {
00577                                 /* Expression */
00578                                 if (-128 != pHVCResult->fdResult.fcResult[i].expressionResult.score[0]) {
00579                                     uint32_t colour;
00580 
00581                                     if (pHVCResult->fdResult.fcResult[i].expressionResult.topExpression > EX_SADNESS) {
00582                                         pHVCResult->fdResult.fcResult[i].expressionResult.topExpression = 0;
00583                                     }
00584                                     switch (pHVCResult->fdResult.fcResult[i].expressionResult.topExpression) {
00585                                         case 1:  colour = 0x0000ffff; break;  /* white */
00586                                         case 2:  colour = 0x0000f0ff; break;  /* yellow */
00587                                         case 3:  colour = 0x000060ff; break;  /* orange */
00588                                         case 4:  colour = 0x00000fff; break;  /* purple */
00589                                         case 5:  colour = 0x0000fff4; break;  /* blue */
00590                                         default: colour = 0x0000ffff; break;  /* white */
00591                                     }
00592                                     DrawString(pExStr[pHVCResult->fdResult.fcResult[i].expressionResult.topExpression], colour);
00593                                 }
00594                             }
00595                         }
00596                     }
00597                 }
00598                 /* Response time */
00599                 memset(Str_disp, 0, sizeof(Str_disp));
00600                 sprintf(Str_disp, "Response time:%dms", resp_time.read_ms());
00601                 ascii_font.Erase(0, 0, 0, 0, 0);
00602                 ascii_font.DrawStr(Str_disp, 0, LCD_PIXEL_HEIGHT - AsciiFont::CHAR_PIX_HEIGHT, 0x0000ffff, 1);
00603             }
00604         } while(0);
00605 
00606         EraseImage();
00607         memset(user_frame_buffer_result, 0, sizeof(user_frame_buffer_result));
00608     }
00609 }