Sample to operate omron HVC-P2 on GR-PEACH.

Dependencies:   AsciiFont

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