その1 USBでつないで通信する
概要
HVC-P2はオムロン製の人物認識カメラモジュールです。このモジュールとGR-PEACH、LCDタッチパネルを組み合わせると、以下のイメージ画像のようにオリジナルカメラが作れます。サンプルについてはこちらのmbedサイトを参照してください。
この特設では、LCDタッチパネルは使わずにHVC-P2との基本的な通信、検出画像の保存、Webカメラへの発展までを紹介します。
人物認識のデモ動画(YouTube)
準備
以下の接続写真を参考に、GR-PEACH、HVC-P2のほかにUSBケーブル(マイクロBタイプ)を2本、USB(タイプA)変換アダプタを準備してください。
また、GR-PEACHの中央部にあるジャンパー(JP3)をショートしてください。これによってUSBホストとして接続する際にVBUSに電源が供給されるようになります。
手順
プロジェクト作成
Webコンパイラで「GR-PEACH_HVC-P2_V1.xx」のテンプレートを使用してプロジェクトを作成してください。基本的なWebコンパイラの使い方は「Webコンパイラでスケッチ」を参照してください。
動作確認
Webコンパイラでビルドして生成されたpeach_sketch.binをGR-PEACHに書き込みます。実行結果をモニターで表示すると以下の結果が得られます。
人物認識を試すサンプル
HVC-P2の人物認識を試してみましょう。以下のサンプルをWebコンパイラでビルドし、実行してみてください。ソース上でダブルクリックすると全選択されます。
正常に動作すると以下のようにシリアルモニターにセンサー値が表示されます。
// 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(){
}