GR-PEACH Special Project: Omron HVC-P2 Human Recognition Camera Module

Part 1. USB Communication

Overview

HVC-P2 is a human recognition camera module produced by Omron. It allows you to build your own camera as shown in the following video, with the combination of a GR-PEACH board and an LCD touch panel. Refer to the mbed site for an HVC-P2 on GR-PEACH sample application.

As the first step, we would like to introduce the basic communication method of HVC-P2, the way to save detected images and development to a web camera in this project, without using an LCD touch panel.

Human Recognition with HVC-P2 and GR-PEACH


Preparation

You will need a GR-PEACH board, HVC-P2, two USB cables (Micro B type), a USB conversion adapter (Type A). Refer to the image on the right for how to connect everything together.

Place a short jumper (JP3) in the center part of GR-PEACH in the circuit. This allows the VBUS to receive power supply when it’s connected as a USB host.


Procedure

Project Creation

Create a project using a template of「GR-PEACH_HVC-P2_V1.xx」with a web compiler.

Refer to the Sketch on Web Compiler project for how to use the basic web compiler.

Operation Check

Write peach_sketch.bin to GR-PEACH, which is built and generated with a web compiler.

The monitor displays the execution result as shown here.


Sample Program for Human Recognition Application

Let’s try a human recognition application with HVC-P2.

Build to execute the following sample program with a web compiler.

Sensor values will be displayed in the serial monitor when GR-PEACH works correctly, as shown here.


// GR-PEACH API
#include <arduino.h>
#include <sd.h>
#include "RTC.h"
#include "USBHostSerial.h"
#include "AsciiFont.h"
#include "JPEG_Converter.h"
// HVC-P2 API
#include "HVCApi.h" // Omron sample
#include "HVCDef.h" // Omron sample
#include "HVCExtraUartFunc.h" // Omron sample
//
#define UART_SETTING_TIMEOUT 1000   /* HVC setting command signal timeout period */
#define UART_EXECUTE_TIMEOUT 7000
 
#define SENSOR_ROLL_ANGLE_DEFAULT            0            /* Camera angle setting (0°) */
 
#define BODY_THRESHOLD_DEFAULT             500            /* Threshold for Human Body Detection */
#define FACE_THRESHOLD_DEFAULT             500            /* Threshold for Face Detection */
#define HAND_THRESHOLD_DEFAULT             500            /* Threshold for Hand Detection */
#define REC_THRESHOLD_DEFAULT              500            /* Threshold for Face Recognition */
 
#define BODY_SIZE_RANGE_MIN_DEFAULT         30            /* Human Body Detection minimum detection size */
#define BODY_SIZE_RANGE_MAX_DEFAULT       8192            /* Human Body Detection maximum detection size */
#define HAND_SIZE_RANGE_MIN_DEFAULT         40            /* Hand Detection minimum detection size */
#define HAND_SIZE_RANGE_MAX_DEFAULT       8192            /* Hand Detection maximum detection size */
#define FACE_SIZE_RANGE_MIN_DEFAULT         64            /* Face Detection minimum detection size */
#define FACE_SIZE_RANGE_MAX_DEFAULT       8192            /* Face Detection maximum detection size */
 
#define FACE_POSE_DEFAULT                    0            /* Face Detection facial pose (frontal face)*/
#define FACE_ANGLE_DEFAULT                   0            /* Face Detection roll angle (±15°)*/
 
static USBHostSerial * p_cdc;
 
extern "C" int UART_SendData(int inDataSize, UINT8 *inData) {
    return p_cdc->writeBuf((char *)inData, inDataSize);
}
extern "C" int UART_ReceiveData(int inTimeOutTime, int inDataSize, UINT8 *outResult) {
    return p_cdc->readBuf((char *)outResult, inDataSize, inTimeOutTime);
}
void led_blink(int pin, int num){
    for(int i = 0; i < num; i++){
        digitalWrite(pin, HIGH);
        delay(200);
        digitalWrite(pin, LOW);
        delay(200);
    }
}
 
void setup(){
    INT32 ret = 0;  /* Return code */
    UINT8 status;
    HVC_RESULT *pHVCResult = NULL;
    HVC_IMAGE *pImage = NULL;
 
    INT32 agleNo;
    HVC_THRESHOLD threshold;
    HVC_SIZERANGE sizeRange;
    INT32 pose;
    INT32 angle;
    INT32 timeOutTime;
    INT32 execFlag;
    INT32 imageNo;
 
    char *pExStr[] = {"?", "Neutral", "Happiness", "Surprise", "Anger", "Sadness"};
 
    int i;
    int ch = 0;
 
    pinMode(PIN_LED_RED, OUTPUT);
    pinMode(PIN_LED_GREEN, OUTPUT);
    pinMode(PIN_LED_BLUE, OUTPUT);
 
    Serial.begin(9600);
    Serial.println("Program starts");
 
    USBHostSerial cdc;
    p_cdc = &cdc; // for HVC P2 API
 
    Serial.print("Waiting USB device...");
    while (!p_cdc->connect()) { // wait for connecting HVC
        led_blink(PIN_LED_RED, 1);
        Thread::wait(500);
    }
    Serial.println("Found.");
 
    led_blink(PIN_LED_GREEN, 2);
    p_cdc->baud(921600);
 
    /*********************************/
    /* Result Structure Allocation   */
    /*********************************/
    pHVCResult = (HVC_RESULT *)malloc(sizeof(HVC_RESULT));
    if ( pHVCResult == NULL ) { /* Error processing */
        Serial.println("Memory Allocation Error");
        mbed_die();
    }
 
    /* Image Structure allocation */
    pImage = (HVC_IMAGE *)malloc(sizeof(HVC_IMAGE));
    if (pImage == NULL) {
        printf("Memory Allocation Error : %08x\n", sizeof(HVC_RESULT));
        mbed_die();
    }
     
    /*********************************/
    /* Set Camera Angle              */
    /*********************************/
    agleNo = SENSOR_ROLL_ANGLE_DEFAULT;
    ret = HVC_SetCameraAngle(UART_SETTING_TIMEOUT, agleNo, &status);
    if ( ret != 0 ) {
        Serial.println("HVCApi(HVC_SetCameraAngle) Error");
    }
    if ( status != 0 ) {
        Serial.println("HVC_SetCameraAngle Response Error");
    }
    agleNo = 0xff;
    ret = HVC_GetCameraAngle(UART_SETTING_TIMEOUT, &agleNo, &status);
    if ( ret != 0 ) {
        Serial.println("HVCApi(HVC_GetCameraAngle) Error");
    }
    if ( status != 0 ) {
        Serial.println("HVC_GetCameraAngle Response Error");
    }
    Serial.println("HVC_GetCameraAngle : ");
    Serial.print("Angle No = ");Serial.println(agleNo);
 
    /*********************************/
    /* Set Threshold Values          */
    /*********************************/
    threshold.bdThreshold = BODY_THRESHOLD_DEFAULT;
    threshold.hdThreshold = HAND_THRESHOLD_DEFAULT;
    threshold.dtThreshold = FACE_THRESHOLD_DEFAULT;
    threshold.rsThreshold = REC_THRESHOLD_DEFAULT;
    ret = HVC_SetThreshold(UART_SETTING_TIMEOUT, &threshold, &status);
    if ( ret != 0 ) {
        Serial.println("HVCApi(HVC_SetThreshold) Error");
    }
    if ( status != 0 ) {
        Serial.println("HVC_SetThreshold Response Error");
    }
    threshold.bdThreshold = 0;
    threshold.hdThreshold = 0;
    threshold.dtThreshold = 0;
    threshold.rsThreshold = 0;
    ret = HVC_GetThreshold(UART_SETTING_TIMEOUT, &threshold, &status);
    if ( ret != 0 ) {
        Serial.println("HVCApi(HVC_GetThreshold) Error");
    }
    if ( status != 0 ) {
        Serial.println("HVC_GetThreshold Response Error");
    }
    Serial.println("HVC_GetThreshold :");
    Serial.print("Body = ");Serial.println(threshold.bdThreshold);
    Serial.print("Hand = ");Serial.println(threshold.hdThreshold);
    Serial.print("Face = ");Serial.println(threshold.dtThreshold);
    Serial.print("Recognition = ");Serial.println(threshold.rsThreshold);
 
    /*********************************/
    /* Set Detection Size            */
    /*********************************/
    sizeRange.bdMinSize = BODY_SIZE_RANGE_MIN_DEFAULT;
    sizeRange.bdMaxSize = BODY_SIZE_RANGE_MAX_DEFAULT;
    sizeRange.hdMinSize = HAND_SIZE_RANGE_MIN_DEFAULT;
    sizeRange.hdMaxSize = HAND_SIZE_RANGE_MAX_DEFAULT;
    sizeRange.dtMinSize = FACE_SIZE_RANGE_MIN_DEFAULT;
    sizeRange.dtMaxSize = FACE_SIZE_RANGE_MAX_DEFAULT;
    ret = HVC_SetSizeRange(UART_SETTING_TIMEOUT, &sizeRange, &status);
    if ( ret != 0 ) {
        Serial.println("HVCApi(HVC_SetSizeRange) Error");
    }
    if ( status != 0 ) {
        Serial.println("HVC_SetSizeRange Response Error");
    }
    sizeRange.bdMinSize = 0;
    sizeRange.bdMaxSize = 0;
    sizeRange.hdMinSize = 0;
    sizeRange.hdMaxSize = 0;
    sizeRange.dtMinSize = 0;
    sizeRange.dtMaxSize = 0;
    ret = HVC_GetSizeRange(UART_SETTING_TIMEOUT, &sizeRange, &status);
    if ( ret != 0 ) {
        Serial.println("HVCApi(HVC_GetSizeRange) Error");
    }
    if ( status != 0 ) {
        Serial.println("HVC_GetSizeRange Response Error");
    }
    Serial.println("HVC_GetSizeRange :");
    Serial.print("Body = ");Serial.print(sizeRange.bdMinSize);Serial.println(sizeRange.bdMaxSize);
    Serial.print("Hand = ");Serial.print(sizeRange.hdMinSize);Serial.println(sizeRange.hdMaxSize);
    Serial.print("Face = ");Serial.print(sizeRange.dtMinSize);Serial.println(sizeRange.dtMaxSize);
 
    /*********************************/
    /* Set Face Angle                */
    /*********************************/
    pose = FACE_POSE_DEFAULT;
    angle = FACE_ANGLE_DEFAULT;
    ret = HVC_SetFaceDetectionAngle(UART_SETTING_TIMEOUT, pose, angle, &status);
    if ( ret != 0 ) {
        Serial.println("HVCApi(HVC_SetFaceDetectionAngle) Error");
    }
    if ( status != 0 ) {
        Serial.println("HVC_SetFaceDetectionAngle Response Error");
    }
    pose = 0xff;
    angle = 0xff;
    ret = HVC_GetFaceDetectionAngle(UART_SETTING_TIMEOUT, &pose, &angle, &status);
    if ( ret != 0 ) {
        Serial.println("HVCApi(HVC_GetFaceDetectionAngle) Error");
    }
    if ( status != 0 ) {
        Serial.println("HVC_GetFaceDetectionAngle Response Error");
    }
    Serial.println("HVC_GetFaceDetectionAngle :");
    Serial.print("Pose = ");Serial.println(pose);
    Serial.print("Angle = ");Serial.println(angle);
 
    /*********************************/
    /* Execute Detection             */
    /*********************************/
    do{
        timeOutTime = UART_EXECUTE_TIMEOUT;
//        execFlag = HVC_ACTIV_BODY_DETECTION | HVC_ACTIV_HAND_DETECTION | HVC_ACTIV_FACE_DETECTION | HVC_ACTIV_FACE_DIRECTION |
//                 HVC_ACTIV_AGE_ESTIMATION | HVC_ACTIV_GENDER_ESTIMATION | HVC_ACTIV_GAZE_ESTIMATION | HVC_ACTIV_BLINK_ESTIMATION |
//                 HVC_ACTIV_EXPRESSION_ESTIMATION;
        execFlag = HVC_ACTIV_FACE_DETECTION | HVC_ACTIV_FACE_DIRECTION |
                 HVC_ACTIV_AGE_ESTIMATION | HVC_ACTIV_GENDER_ESTIMATION | HVC_ACTIV_GAZE_ESTIMATION | HVC_ACTIV_BLINK_ESTIMATION |
                 HVC_ACTIV_EXPRESSION_ESTIMATION;
        imageNo = HVC_EXECUTE_IMAGE_QVGA_HALF; /* HVC_EXECUTE_IMAGE_NONE; */
        ret = HVC_ExecuteEx(timeOutTime, execFlag, imageNo, pHVCResult, &status);
        if ( ret != 0 ) {
            Serial.println("HVCApi(HVC_ExecuteEx) Error");
            Serial.println(ret);
        }
        if ( status != 0 ) {
            Serial.println("HVC_ExecuteEx Response Error");
        }
 
        if(pHVCResult->executedFunc & HVC_ACTIV_BODY_DETECTION){
            /* Body Detection result string */
            Serial.print("Body result count:"); Serial.println(pHVCResult->bdResult.num);
            for(i = 0; i < pHVCResult->bdResult.num; i++){
                Serial.print("Index:"); Serial.println(i);
                Serial.print("X = "); Serial.print(pHVCResult->bdResult.bdResult[i].posX);
                Serial.print(" Y = "); Serial.print(pHVCResult->bdResult.bdResult[i].posY);
                Serial.print(" Size = "); Serial.print(pHVCResult->bdResult.bdResult[i].size);
                Serial.print(" Confidence = "); Serial.print(pHVCResult->bdResult.bdResult[i].confidence);
                Serial.println();
            }
        }
        if(pHVCResult->executedFunc & HVC_ACTIV_HAND_DETECTION){
            /* Hand Detection result string */
            Serial.print("Hand result count:"); Serial.println(pHVCResult->hdResult.num);
            for(i = 0; i < pHVCResult->hdResult.num; i++){
                Serial.print("Index:"); Serial.println(i);
                Serial.print("X = "); Serial.print(pHVCResult->hdResult.hdResult[i].posX);
                Serial.print(" Y = "); Serial.print(pHVCResult->hdResult.hdResult[i].posY);
                Serial.print(" Size = "); Serial.print(pHVCResult->hdResult.hdResult[i].size);
                Serial.print(" Confidence = "); Serial.print(pHVCResult->hdResult.hdResult[i].confidence);
                Serial.println();
            }
        }
        /* Face Detection result string */
        if(pHVCResult->executedFunc &
                (HVC_ACTIV_FACE_DETECTION | HVC_ACTIV_FACE_DIRECTION |
                 HVC_ACTIV_AGE_ESTIMATION | HVC_ACTIV_GENDER_ESTIMATION |
                 HVC_ACTIV_GAZE_ESTIMATION | HVC_ACTIV_BLINK_ESTIMATION |
                 HVC_ACTIV_EXPRESSION_ESTIMATION | HVC_ACTIV_FACE_RECOGNITION)){
            Serial.print("Face result count:"); Serial.println(pHVCResult->fdResult.num);
            for(i = 0; i < pHVCResult->fdResult.num; i++){
                if(pHVCResult->executedFunc & HVC_ACTIV_FACE_DETECTION){
                    /* Detection */
                    Serial.print("Index:"); Serial.println(i);
                    Serial.print("X = "); Serial.print(pHVCResult->fdResult.fcResult[i].dtResult.posX);
                    Serial.print(" Y = "); Serial.print(pHVCResult->fdResult.fcResult[i].dtResult.posY);
                    Serial.print(" Size = "); Serial.print(pHVCResult->fdResult.fcResult[i].dtResult.size);
                    Serial.print(" Confidence = "); Serial.print(pHVCResult->fdResult.fcResult[i].dtResult.confidence);
                    Serial.println();
                }
                if(pHVCResult->executedFunc & HVC_ACTIV_FACE_DIRECTION){
                    /* Face Direction */
                    Serial.print("Face Direction : ");
                    Serial.print("LR = "); Serial.print(pHVCResult->fdResult.fcResult[i].dirResult.yaw);
                    Serial.print(" UD = "); Serial.print(pHVCResult->fdResult.fcResult[i].dirResult.pitch);
                    Serial.print(" Roll = "); Serial.print(pHVCResult->fdResult.fcResult[i].dirResult.roll);
                    Serial.print(" Confidence = "); Serial.print(pHVCResult->fdResult.fcResult[i].dirResult.confidence);
                    Serial.println();
                }
                if(pHVCResult->executedFunc & HVC_ACTIV_AGE_ESTIMATION){
                    /* Age */
                    if(-128 == pHVCResult->fdResult.fcResult[i].ageResult.age){
                        Serial.println("Age Estimation not possible");
                    } else {
                        Serial.print("Age = ");
                        Serial.print(pHVCResult->fdResult.fcResult[i].ageResult.age);
                        Serial.print(" Confidence = ");
                        Serial.print(pHVCResult->fdResult.fcResult[i].ageResult.confidence);
                        Serial.println();
                    }
                }
                if(pHVCResult->executedFunc & HVC_ACTIV_GENDER_ESTIMATION){
                    /* Gender */
                    if(-128 == pHVCResult->fdResult.fcResult[i].genderResult.gender){
                        Serial.println("Gender Estimation not possible");
                    }
                    else{
                        if(1 == pHVCResult->fdResult.fcResult[i].genderResult.gender){
                            Serial.print("Gender Male Confidence = ");
                            Serial.print(pHVCResult->fdResult.fcResult[i].genderResult.confidence);
                            Serial.println();
                        }
                        else{
                            Serial.print("Gender Female Confidence = ");
                            Serial.print(pHVCResult->fdResult.fcResult[i].genderResult.confidence);
                            Serial.println();
                        }
                    }
                }
                if(pHVCResult->executedFunc & HVC_ACTIV_GAZE_ESTIMATION){
                    /* Gaze */
                    if((-128 == pHVCResult->fdResult.fcResult[i].gazeResult.gazeLR) ||
                        (-128 == pHVCResult->fdResult.fcResult[i].gazeResult.gazeUD)){
                        Serial.println("Gaze Estimation not possible");
                    }
                    else{
                        Serial.print("Gaze : ");
                        Serial.print("LR = "); Serial.print(pHVCResult->fdResult.fcResult[i].gazeResult.gazeLR);
                        Serial.print(" UD = "); Serial.print(pHVCResult->fdResult.fcResult[i].gazeResult.gazeUD);
                        Serial.println();
                    }
                }
                if(pHVCResult->executedFunc & HVC_ACTIV_BLINK_ESTIMATION){
                    /* Blink */
                    if((-128 == pHVCResult->fdResult.fcResult[i].blinkResult.ratioL) ||
                        (-128 == pHVCResult->fdResult.fcResult[i].blinkResult.ratioR)){
                        Serial.println("Gaze Estimation not possible");
                    }
                    else{
                        Serial.print("Blink : ");
                        Serial.print("Left = "); Serial.print(pHVCResult->fdResult.fcResult[i].blinkResult.ratioL);
                        Serial.print(" Right = "); Serial.print(pHVCResult->fdResult.fcResult[i].blinkResult.ratioR);
                        Serial.println();
                    }
                }
                if(pHVCResult->executedFunc & HVC_ACTIV_EXPRESSION_ESTIMATION){
                    /* Expression */
                    if(-128 == pHVCResult->fdResult.fcResult[i].expressionResult.score[0]){
                        Serial.println("Expression Estimation not possible");
                    }
                    else{
                        if(pHVCResult->fdResult.fcResult[i].expressionResult.topExpression > EX_SADNESS){
                            pHVCResult->fdResult.fcResult[i].expressionResult.topExpression = 0;
                        }
                        Serial.print("Expression : ");
                        Serial.print("Expression = "); Serial.print(pExStr[pHVCResult->fdResult.fcResult[i].expressionResult.topExpression]);
                        Serial.print(" Score = ");
                        Serial.print(pHVCResult->fdResult.fcResult[i].expressionResult.score[0]);
                        Serial.print(" ");
                        Serial.print(pHVCResult->fdResult.fcResult[i].expressionResult.score[1]);
                        Serial.print(" ");
                        Serial.print(pHVCResult->fdResult.fcResult[i].expressionResult.score[2]);
                        Serial.print(" ");
                        Serial.print(pHVCResult->fdResult.fcResult[i].expressionResult.score[3]);
                        Serial.print(" ");
                        Serial.print(pHVCResult->fdResult.fcResult[i].expressionResult.score[4]);
                        Serial.print(" Degree = ");
                        Serial.print(pHVCResult->fdResult.fcResult[i].expressionResult.degree);
                        Serial.println();
                    }
                }
            }
        }
        if(Serial.available()){
            ch = Serial.read();
        }
 
    } while ( ch != ' ');
 
 
    while(1);
 
}
 
void loop(){
}