Sample program that can send the recognition data from HVC-P2 to Fujitsu IoT Platform using REST (HTTP)

Dependencies:   AsciiFont GR-PEACH_video GraphicsFramework LCD_shield_config R_BSP USBHost_custom easy-connect-gr-peach mbed-http picojson

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 "iot_platform.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     0x1FF,
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 /* IoT ready semaphore */
00064 Semaphore iot_ready_semaphore(1);
00065 int semaphore_wait_ret;
00066 
00067 /****** Image Recognition ******/
00068 extern "C" int UART_SendData(int inDataSize, UINT8 *inData) {
00069     return serial.writeBuf((char *)inData, inDataSize);
00070 }
00071 
00072 extern "C" int UART_ReceiveData(int inTimeOutTime, int inDataSize, UINT8 *outResult) {
00073     return serial.readBuf((char *)outResult, inDataSize, inTimeOutTime);
00074 }
00075 
00076 void SetRegistrationrReq(void) {
00077     registrationr_req = true;
00078 }
00079 
00080 void SetSettingReq(void) {
00081     setting_req = true;
00082 }
00083 
00084 recognition_setting_t * GetRecognitionSettingPointer(void) {
00085     return &setting;
00086 }
00087 
00088 static void EraseImage(void) {
00089     uint32_t i = 0;
00090     while (i < sizeof(user_frame_buffer0)) {
00091         user_frame_buffer0[i++] = 0x10;
00092         user_frame_buffer0[i++] = 0x80;
00093     }
00094 }
00095 
00096 static void DrawImage(int x, int y, int nWidth, int nHeight, UINT8 *unImageBuffer, int magnification) {
00097     int idx_base;
00098     int idx_w = 0;
00099     int wk_tmp = 0;
00100     int i;
00101     int j;
00102     int k;
00103     int idx_r = 0;
00104 
00105     if (magnification <= 0) {
00106         return;
00107     }
00108 
00109     idx_base = (x + (DISP_PIXEL_WIDTH * y)) * RESULT_BUFFER_BYTE_PER_PIXEL;
00110 
00111     for (i = 0; i < nHeight; i++) {
00112         idx_w = idx_base + (DISP_PIXEL_WIDTH * RESULT_BUFFER_BYTE_PER_PIXEL * i) * magnification;
00113         wk_tmp = idx_w;
00114         for (j = 0; j < nWidth; j++) {
00115             for (k = 0; k < magnification; k++) {
00116                 user_frame_buffer0[idx_w] = unImageBuffer[idx_r];
00117                 idx_w += 2;
00118             }
00119             idx_r++;
00120         }
00121         for (k = 1; k < magnification; k++) {
00122             memcpy(&user_frame_buffer0[wk_tmp + (DISP_PIXEL_WIDTH * RESULT_BUFFER_BYTE_PER_PIXEL * k)], &user_frame_buffer0[wk_tmp], idx_w - wk_tmp);
00123         }
00124     }
00125 }
00126 
00127 static void DrawSquare(int x, int y, int size, uint32_t const colour) {
00128     int wk_x;
00129     int wk_y;
00130     int wk_w = 0;
00131     int wk_h = 0;
00132     int idx_base;
00133     int wk_idx;
00134     int i;
00135     int j;
00136     uint8_t coller_pix[RESULT_BUFFER_BYTE_PER_PIXEL];  /* ARGB4444 */
00137     bool l_draw = true;
00138     bool r_draw = true;
00139     bool t_draw = true;
00140     bool b_draw = true;
00141 
00142     if ((x - (size / 2)) < 0) {
00143         l_draw = false;
00144         wk_w += x;
00145         wk_x = 0;
00146     } else {
00147         wk_w += (size / 2);
00148         wk_x = x - (size / 2);
00149     }
00150 
00151     if ((x + (size / 2)) >= 1600) {
00152         r_draw = false;
00153         wk_w += (1600 - x);
00154     } else {
00155         wk_w += (size / 2);
00156     }
00157 
00158     if ((y - (size / 2)) < 0) {
00159         t_draw = false;
00160         wk_h += y;
00161         wk_y = 0;
00162     } else {
00163         wk_h += (size / 2);
00164         wk_y = y - (size / 2);
00165     }
00166 
00167     if ((y + (size / 2)) >= 1200) {
00168         b_draw = false;
00169         wk_h += (1200 - y);
00170     } else {
00171         wk_h += (size / 2);
00172     }
00173 
00174     wk_x = wk_x / 5;
00175     wk_y = wk_y / 5;
00176     wk_w = wk_w / 5;
00177     wk_h = wk_h / 5;
00178 
00179     if ((colour == 0x0000f0f0) || (colour == 0x0000fff4)) {
00180         str_draw_x = wk_x;
00181         str_draw_y = wk_y + wk_h + 1;
00182     }
00183 
00184     idx_base = (wk_x + (DISP_PIXEL_WIDTH * wk_y)) * RESULT_BUFFER_BYTE_PER_PIXEL;
00185 
00186     /* Select color */
00187     coller_pix[0] = (colour >> 8) & 0xff;  /* 4:Green 4:Blue */
00188     coller_pix[1] = colour & 0xff;         /* 4:Alpha 4:Red  */
00189 
00190     /* top */
00191     if (t_draw) {
00192         wk_idx = idx_base;
00193         for (j = 0; j < wk_w; j++) {
00194             user_frame_buffer_result[wk_idx++] = coller_pix[0];
00195             user_frame_buffer_result[wk_idx++] = coller_pix[1];
00196         }
00197     }
00198 
00199     /* middle */
00200     for (i = 1; i < (wk_h - 1); i++) {
00201         wk_idx = idx_base + (DISP_PIXEL_WIDTH * RESULT_BUFFER_BYTE_PER_PIXEL * i);
00202         if (l_draw) {
00203             user_frame_buffer_result[wk_idx + 0] = coller_pix[0];
00204             user_frame_buffer_result[wk_idx + 1] = coller_pix[1];
00205         }
00206         wk_idx += (wk_w - 1) * 2;
00207         if (r_draw) {
00208             user_frame_buffer_result[wk_idx + 0] = coller_pix[0];
00209             user_frame_buffer_result[wk_idx + 1] = coller_pix[1];
00210         }
00211     }
00212 
00213     /* bottom */
00214     if (b_draw) {
00215         wk_idx = idx_base + (DISP_PIXEL_WIDTH * RESULT_BUFFER_BYTE_PER_PIXEL * (wk_h - 1));
00216         for (j = 0; j < wk_w; j++) {
00217             user_frame_buffer_result[wk_idx++] = coller_pix[0];
00218             user_frame_buffer_result[wk_idx++] = coller_pix[1];
00219         }
00220     }
00221 }
00222 
00223 static void DrawString(const char * str, uint32_t const colour) {
00224     ascii_font.Erase(0x00000090, str_draw_x, str_draw_y,
00225                      (AsciiFont::CHAR_PIX_WIDTH * strlen(str) + 2),
00226                      (AsciiFont::CHAR_PIX_HEIGHT + 2));
00227     ascii_font.DrawStr(str, str_draw_x + 1, str_draw_y + 1, colour, 1);
00228     str_draw_y += AsciiFont::CHAR_PIX_HEIGHT + 1;
00229 }
00230 
00231 static void button_fall(void) {
00232     if (imageNo_setting == HVC_EXECUTE_IMAGE_NONE) {
00233         imageNo_setting = HVC_EXECUTE_IMAGE_QVGA_HALF;
00234     } else if (imageNo_setting == HVC_EXECUTE_IMAGE_QVGA_HALF) {
00235         imageNo_setting = HVC_EXECUTE_IMAGE_QVGA;
00236     } else {
00237         imageNo_setting = HVC_EXECUTE_IMAGE_NONE;
00238     }
00239 }
00240 
00241 void init_recognition_layers(DisplayBase * p_display) {
00242     DisplayBase::rect_t rect;
00243 
00244     /* The layer by which the image is drawn */
00245     rect.vs = 0;
00246     rect.vw = DISP_PIXEL_HEIGHT;
00247     rect.hs = 0;
00248     rect.hw = DISP_PIXEL_WIDTH;
00249     p_display->Graphics_Read_Setting(
00250         DisplayBase::GRAPHICS_LAYER_0,
00251         (void *)user_frame_buffer0,
00252         FRAME_BUFFER_STRIDE,
00253         DisplayBase::GRAPHICS_FORMAT_YCBCR422,
00254         DisplayBase::WR_RD_WRSWA_32_16BIT,
00255         &rect
00256     );
00257     p_display->Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
00258 
00259     /* The layer by which the image recognition is drawn */
00260     rect.vs = 0;
00261     rect.vw = LCD_PIXEL_HEIGHT;
00262     rect.hs = 0;
00263     rect.hw = DISP_PIXEL_WIDTH;
00264     p_display->Graphics_Read_Setting(
00265         DisplayBase::GRAPHICS_LAYER_1,
00266         (void *)user_frame_buffer_result,
00267         RESULT_BUFFER_STRIDE,
00268         DisplayBase::GRAPHICS_FORMAT_ARGB4444,
00269         DisplayBase::WR_RD_WRSWA_32_16BIT,
00270         &rect
00271     );
00272     p_display->Graphics_Start(DisplayBase::GRAPHICS_LAYER_1);
00273 }
00274 
00275 void recognition_task(DisplayBase * p_display) {
00276     INT32 ret = 0;
00277     UINT8 status;
00278     HVC_VERSION version;
00279     HVC_RESULT *pHVCResult = NULL;
00280     HVC_IMAGE *pImage = NULL;
00281     INT32 execFlag;
00282     INT32 imageNo;
00283     INT32 userID;
00284     INT32 next_userID;
00285     INT32 dataID;
00286     const char *pExStr[] = {"?", "Neutral", "Happiness", "Surprise", "Anger", "Sadness"};
00287     uint32_t i;
00288     char Str_disp[32];
00289     Timer resp_time;
00290 
00291     /* Register the button */
00292     button.fall(&button_fall);
00293 
00294     /* Initializing Recognition layers */
00295     EraseImage();
00296     memset(user_frame_buffer_result, 0, sizeof(user_frame_buffer_result));
00297     init_recognition_layers(p_display);
00298 
00299     /* Result Structure Allocation */
00300     pHVCResult = (HVC_RESULT *)malloc(sizeof(HVC_RESULT));
00301     if (pHVCResult == NULL) {
00302         printf("Memory Allocation Error : %08x\n", sizeof(HVC_RESULT));
00303         mbed_die();
00304     }
00305 
00306     /* Image Structure allocation */
00307     pImage = (HVC_IMAGE *)malloc(sizeof(HVC_IMAGE));
00308     if (pImage == NULL) {
00309         printf("Memory Allocation Error : %08x\n", sizeof(HVC_RESULT));
00310         mbed_die();
00311     }
00312 
00313     while (1) {
00314         /* try to connect a serial device */
00315         while (!serial.connect()) {
00316             Thread::wait(500);
00317         }
00318         serial.baud(921600);
00319         setting_req = true;
00320 
00321         do {
00322             /* Initializing variables */
00323             next_userID = 0;
00324             dataID = 0;
00325 
00326             /* Get Model and Version */
00327             ret = HVC_GetVersion(UART_SETTING_TIMEOUT, &version, &status);
00328             if ((ret != 0) || (status != 0)) {
00329                 break;
00330             }
00331 
00332             while (1) {
00333                 if (!serial.connected()) {
00334                     break;
00335                 }
00336 
00337                 /* Execute Setting */
00338                 if (setting_req) {
00339                     setting_req = false;
00340                     /* Set Camera Angle */
00341                     ret = HVC_SetCameraAngle(UART_SETTING_TIMEOUT, SENSOR_ROLL_ANGLE_DEFAULT, &status);
00342                     if ((ret != 0) || (status != 0)) {
00343                         break;
00344                     }
00345                     /* Set Threshold Values */
00346                     ret = HVC_SetThreshold(UART_SETTING_TIMEOUT, &setting.threshold, &status);
00347                     if ((ret != 0) || (status != 0)) {
00348                         break;
00349                     }
00350                     ret = HVC_GetThreshold(UART_SETTING_TIMEOUT, &setting.threshold, &status);
00351                     if ((ret != 0) || (status != 0)) {
00352                         break;
00353                     }
00354                     /* Set Detection Size */
00355                     ret = HVC_SetSizeRange(UART_SETTING_TIMEOUT, &setting.sizeRange, &status);
00356                     if ((ret != 0) || (status != 0)) {
00357                         break;
00358                     }
00359                     ret = HVC_GetSizeRange(UART_SETTING_TIMEOUT, &setting.sizeRange, &status);
00360                     if ((ret != 0) || (status != 0)) {
00361                         break;
00362                     }
00363                     /* Set Face Angle */
00364                     ret = HVC_SetFaceDetectionAngle(UART_SETTING_TIMEOUT, setting.pose, setting.angle, &status);
00365                     if ((ret != 0) || (status != 0)) {
00366                         break;
00367                     }
00368                     ret = HVC_GetFaceDetectionAngle(UART_SETTING_TIMEOUT, &setting.pose, &setting.angle, &status);
00369                     if ((ret != 0) || (status != 0)) {
00370                         break;
00371                     }
00372                 }
00373 
00374                 /* Execute Registration */
00375                 if (registrationr_req) {
00376                     int wk_width;
00377 
00378                     if ((pHVCResult->fdResult.num == 1) && (pHVCResult->fdResult.fcResult[0].recognitionResult.uid >= 0)) {
00379                         userID = pHVCResult->fdResult.fcResult[0].recognitionResult.uid;
00380                     } else {
00381                         userID = next_userID;
00382                     }
00383                     ret = HVC_Registration(UART_REGIST_EXECUTE_TIMEOUT, userID, dataID, pImage, &status);
00384                     if ((ret == 0) && (status == 0)) {
00385                         if (userID == next_userID) {
00386                             next_userID++;
00387                             if (next_userID >= USER_ID_NUM_MAX) {
00388                                 next_userID = 0;
00389                             }
00390                         }
00391                         memset(user_frame_buffer_result, 0, sizeof(user_frame_buffer_result));
00392                         DrawImage(128, 88, pImage->width, pImage->height, pImage->image, 1);
00393                         memset(Str_disp, 0, sizeof(Str_disp));
00394                         sprintf(Str_disp, "USER%03d", userID + 1);
00395                         wk_width = (AsciiFont::CHAR_PIX_WIDTH * strlen(Str_disp)) + 2;
00396                         ascii_font.Erase(0x00000090, (DISP_PIXEL_WIDTH - wk_width) / 2, 153, wk_width, (AsciiFont::CHAR_PIX_HEIGHT + 2));
00397                         ascii_font.DrawStr(Str_disp, (DISP_PIXEL_WIDTH - wk_width) / 2 + 1, 154, 0x0000ffff, 1);
00398                         Thread::wait(1200);
00399                     } else {
00400                         if (status == 0x02) {
00401                             wk_width = (AsciiFont::CHAR_PIX_WIDTH * (sizeof(ERROR_02) - 1)) + 4;
00402                             ascii_font.Erase(0x00000090, (DISP_PIXEL_WIDTH - wk_width) / 2, 120, wk_width, (AsciiFont::CHAR_PIX_HEIGHT + 3));
00403                             ascii_font.DrawStr(ERROR_02, (DISP_PIXEL_WIDTH - wk_width) / 2 + 2, 121, 0x0000ffff, 1);
00404                             Thread::wait(1500);
00405                         }
00406                     }
00407                     registrationr_req = false;
00408                 }
00409 
00410                 /* Execute Detection */
00411 
00412                 semaphore_wait_ret = iot_ready_semaphore.wait();
00413                 if(semaphore_wait_ret == -1)
00414                 {
00415                     printf("<recog_proc> semaphore error.\n");
00416                 }else{
00417                     execFlag = setting.execFlag;
00418                     if ((execFlag & HVC_ACTIV_FACE_DETECTION) == 0) {
00419                         execFlag &= ~(HVC_ACTIV_AGE_ESTIMATION | HVC_ACTIV_GENDER_ESTIMATION | HVC_ACTIV_EXPRESSION_ESTIMATION);
00420                     }
00421                     imageNo = imageNo_setting;
00422                     resp_time.reset();
00423                     resp_time.start();
00424                     ret = HVC_ExecuteEx(UART_EXECUTE_TIMEOUT, execFlag, imageNo, pHVCResult, &status);
00425                     resp_time.stop();
00426                     if ((ret == 0) && (status == 0)) {
00427                         if (imageNo == HVC_EXECUTE_IMAGE_QVGA_HALF) {
00428                             DrawImage(0, 0, pHVCResult->image.width, pHVCResult->image.height, pHVCResult->image.image, 2);
00429                         } else if (imageNo == HVC_EXECUTE_IMAGE_QVGA) {
00430                             DrawImage(0, 0, pHVCResult->image.width, pHVCResult->image.height, pHVCResult->image.image, 1);
00431                         } else {
00432                             EraseImage();
00433                         }
00434                         memset(user_frame_buffer_result, 0, sizeof(user_frame_buffer_result));
00435                         
00436                         if (pHVCResult->executedFunc & HVC_ACTIV_BODY_DETECTION) {
00437                             /* Body Detection result */
00438                             result_hvcp2_bd_cnt = pHVCResult->bdResult.num;
00439                             for (i = 0; i < pHVCResult->bdResult.num; i++) {
00440                                 DrawSquare(pHVCResult->bdResult.bdResult[i].posX, 
00441                                     pHVCResult->bdResult.bdResult[i].posY,
00442                                     pHVCResult->bdResult.bdResult[i].size,
00443                                     0x000000ff);
00444                                 result_hvcp2_bd[i].body_rectangle.MinX = pHVCResult->bdResult.bdResult[i].posX;
00445                                 result_hvcp2_bd[i].body_rectangle.MinY = pHVCResult->bdResult.bdResult[i].posY;
00446                                 result_hvcp2_bd[i].body_rectangle.Width = pHVCResult->bdResult.bdResult[i].size;
00447                                 result_hvcp2_bd[i].body_rectangle.Height = pHVCResult->bdResult.bdResult[i].size;
00448                             }
00449                         }
00450 
00451                         /* Face Detection result */
00452                         if (pHVCResult->executedFunc &
00453                             (HVC_ACTIV_FACE_DETECTION | HVC_ACTIV_FACE_DIRECTION |
00454                                 HVC_ACTIV_AGE_ESTIMATION | HVC_ACTIV_GENDER_ESTIMATION |
00455                                 HVC_ACTIV_GAZE_ESTIMATION | HVC_ACTIV_BLINK_ESTIMATION |
00456                                 HVC_ACTIV_EXPRESSION_ESTIMATION | HVC_ACTIV_FACE_RECOGNITION)){
00457                             /* Face Detection result */
00458                             result_hvcp2_fd_cnt = pHVCResult->fdResult.num;
00459                             for (i = 0; i < pHVCResult->fdResult.num; i++) {
00460                                 if (pHVCResult->executedFunc & HVC_ACTIV_FACE_DETECTION) {
00461                                     uint32_t detection_colour = 0x0000f0f0; /* green */
00462                                     if (pHVCResult->executedFunc & HVC_ACTIV_FACE_RECOGNITION) {
00463                                         if (pHVCResult->fdResult.fcResult[i].recognitionResult.uid >= 0) {
00464                                             detection_colour = 0x0000fff4; /* blue */
00465                                         }
00466                                     }
00467                                     /* Detection */
00468                                     DrawSquare(pHVCResult->fdResult.fcResult[i].dtResult.posX,
00469                                         pHVCResult->fdResult.fcResult[i].dtResult.posY,
00470                                         pHVCResult->fdResult.fcResult[i].dtResult.size,
00471                                         detection_colour);
00472                                     
00473                                     result_hvcp2_fd[i].face_rectangle.MinX = pHVCResult->fdResult.fcResult[i].dtResult.posX;
00474                                     result_hvcp2_fd[i].face_rectangle.MinY = pHVCResult->fdResult.fcResult[i].dtResult.posY;
00475                                     result_hvcp2_fd[i].face_rectangle.Width = pHVCResult->fdResult.fcResult[i].dtResult.size;
00476                                     result_hvcp2_fd[i].face_rectangle.Height = pHVCResult->fdResult.fcResult[i].dtResult.size;
00477                                 }
00478                                 if (pHVCResult->executedFunc & HVC_ACTIV_FACE_RECOGNITION) {
00479                                     /* Recognition */
00480                                     if (-128 == pHVCResult->fdResult.fcResult[i].recognitionResult.uid) {
00481                                         DrawString("Not possible", 0x0000f0ff);
00482                                     } else if (pHVCResult->fdResult.fcResult[i].recognitionResult.uid < 0) {
00483                                         DrawString("Not registered", 0x0000f0ff);
00484                                     } else {
00485                                         memset(Str_disp, 0, sizeof(Str_disp));
00486                                         sprintf(Str_disp, "USER%03d", pHVCResult->fdResult.fcResult[i].recognitionResult.uid + 1);
00487                                         DrawString(Str_disp, 0x0000f0ff);
00488                                     }
00489                                 }
00490                                 if (pHVCResult->executedFunc & HVC_ACTIV_AGE_ESTIMATION) {
00491                                     /* Age */
00492                                     if (-128 != pHVCResult->fdResult.fcResult[i].ageResult.age) {
00493                                         memset(Str_disp, 0, sizeof(Str_disp));
00494                                         sprintf(Str_disp, "Age:%d", pHVCResult->fdResult.fcResult[i].ageResult.age);
00495                                         DrawString(Str_disp, 0x0000f0ff);
00496                                     }
00497                                 }
00498                                 if (pHVCResult->executedFunc & HVC_ACTIV_GENDER_ESTIMATION) {
00499                                     /* Gender */
00500                                     if (-128 != pHVCResult->fdResult.fcResult[i].genderResult.gender) {
00501                                         if (1 == pHVCResult->fdResult.fcResult[i].genderResult.gender) {
00502                                             DrawString("Male", 0x0000fff4);
00503                                         } else {
00504                                             DrawString("Female", 0x00006dff);
00505                                         }
00506                                     }
00507                                 }
00508                                 if (pHVCResult->executedFunc & HVC_ACTIV_EXPRESSION_ESTIMATION) {
00509                                     /* Expression */
00510                                     if (-128 != pHVCResult->fdResult.fcResult[i].expressionResult.score[0]) {
00511                                         uint32_t colour;
00512 
00513                                         result_hvcp2_fd[i].scores.score_neutral = pHVCResult->fdResult.fcResult[i].expressionResult.score[0];
00514                                         result_hvcp2_fd[i].scores.score_anger = pHVCResult->fdResult.fcResult[i].expressionResult.score[1];
00515                                         result_hvcp2_fd[i].scores.score_happiness = pHVCResult->fdResult.fcResult[i].expressionResult.score[2];
00516                                         result_hvcp2_fd[i].scores.score_surprise = pHVCResult->fdResult.fcResult[i].expressionResult.score[3];
00517                                         result_hvcp2_fd[i].scores.score_sadness = pHVCResult->fdResult.fcResult[i].expressionResult.score[4];
00518                                         result_hvcp2_fd[i].age.age = pHVCResult->fdResult.fcResult[i].ageResult.age;
00519                                         result_hvcp2_fd[i].gender.gender = pHVCResult->fdResult.fcResult[i].genderResult.gender;
00520 
00521                                         if (pHVCResult->fdResult.fcResult[i].expressionResult.topExpression > EX_SADNESS) {
00522                                             pHVCResult->fdResult.fcResult[i].expressionResult.topExpression = 0;
00523                                         }
00524                                         switch (pHVCResult->fdResult.fcResult[i].expressionResult.topExpression) {
00525                                             case 1:  colour = 0x0000ffff; break;  /* white */
00526                                             case 2:  colour = 0x0000f0ff; break;  /* yellow */
00527                                             case 3:  colour = 0x000060ff; break;  /* orange */
00528                                             case 4:  colour = 0x00000fff; break;  /* purple */
00529                                             case 5:  colour = 0x0000fff4; break;  /* blue */
00530                                             default: colour = 0x0000ffff; break;  /* white */
00531                                         }
00532                                         DrawString(pExStr[pHVCResult->fdResult.fcResult[i].expressionResult.topExpression], colour);
00533                                     }
00534                                 }
00535                             }
00536                         }
00537                     }
00538                     iot_ready_semaphore.release();
00539                 }
00540 
00541                 /* Response time */
00542                 memset(Str_disp, 0, sizeof(Str_disp));
00543                 sprintf(Str_disp, "Response time:%dms", resp_time.read_ms());
00544                 ascii_font.Erase(0, 0, 0, 0, 0);
00545                 ascii_font.DrawStr(Str_disp, 0, LCD_PIXEL_HEIGHT - AsciiFont::CHAR_PIX_HEIGHT, 0x0000ffff, 1);
00546             }
00547         } while(0);
00548 
00549         EraseImage();
00550         memset(user_frame_buffer_result, 0, sizeof(user_frame_buffer_result));
00551     }
00552 }
00553