2015년 12월 17일 목요일

EmoStateLogger

SDK Main page 에 있는 EmoState 에 대한 설명을 보면,

An EmoState is an opaque data structure that contains the current state of the Emotiv detections, which, in turn, reflect the user’s facial, emotional and cognitive state.
EmoState data is retrieved by Emotiv API functions that are prefixed with IES_.

'EmoState 는 사용자의 표정, 감정, 인식 상태에 대한 탐지 상태를 나타내는 opaque data 이며 IES_ prefix 를 가진 API 로 조회 할 수 있다.' 라고 기술 되어 있는데....
결정적으로 IES_ prefix 를 가진 API 는 없다. IEmoStateDLL.h 를 살펴보면 죄다 IS_ 로 시작한다. 단순한 technical writer 의 실수라고 하기에는 3.3.0 의 버젼을 유지하는 (비싼) 상품을 판매하는 회사가 할 것은 아닌 듯. 좀 물어 봐야 겠다. 여튼 이 예제를 통해 위와 같은 정보를 얻을 수 있다고 한다.

위치 : community-sdk/example/C++/EmoStateLogger
기준 commit : 6a20813229ff56cf0c0040cfddaaa086d7e27ea4
컴파일 : 정상
실행 : 비정상 
결과물 : 텍스트 파일 (사용자 정의)

소스 코드에서 SDK API 호출 부분만 살펴 보면,

...
79 if (IEE_EngineConnect() != EDK_OK) {
...
114 state = IEE_EngineGetNextEvent(eEvent);
...
119 IEE_Event_t eventType = IEE_EmoEngineEventGetType(eEvent);
120 IEE_EmoEngineEventGetUserId(eEvent, &userID);
...
125 IEE_EmoEngineEventGetEmoState(eEvent, eState);
...
131 logEmoState(ofs, userID, eState, writeHeader);
...
164 void logEmoState(std::ostream& os, unsigned int userID,
165 EmoStateHandle eState, bool withHeader) {
...
187 // Log the time stamp and user ID
188 os << IS_GetTimeFromStart(eState) << ",";
189 os << userID << ",";
190 os << static_cast<int>(IS_GetWirelessSignalStatus(eState)) << ",";
191
192 // FacialExpression Suite results
193 os << IS_FacialExpressionIsBlink(eState) << ",";
194 os << IS_FacialExpressionIsLeftWink(eState) << ",";
195 os << IS_FacialExpressionIsRightWink(eState) << ",";
...
201 IEE_FacialExpressionAlgo_t upperFaceAction =
202 IS_FacialExpressionGetUpperFaceAction(eState);
203 float upperFacePower = IS_FacialExpressionGetUpperFaceActionPower(eState);
204
205 IEE_FacialExpressionAlgo_t lowerFaceAction =
206 IS_FacialExpressionGetLowerFaceAction(eState);
207 float lowerFacePower = IS_FacialExpressionGetLowerFaceActionPower(eState);
208
209 expressivStates[ upperFaceAction ] = upperFacePower;
210 expressivStates[ lowerFaceAction ] = lowerFacePower;
211
212 os << expressivStates[ FE_SURPRISE ] << ","; // eyebrow
213 os << expressivStates[ FE_FROWN ] << ","; // furrow
214 os << expressivStates[ FE_SMILE ] << ","; // smile
215 os << expressivStates[ FE_CLENCH ] << ","; // clench
216
217 // MentalCommand Suite results
218 os << static_cast<int>(IS_MentalCommandGetCurrentAction(eState)) << ",";
219 os << IS_MentalCommandGetCurrentActionPower(eState);
...

코드를 읽어 보면
1. IEE_EngineConnect() 를 통해 hidraw 장치를 열어서 insight 와의 연결을 초기화 하고
2. Event 를 얻어 와서
3. 사용자 ID와 EmoState 를 얻어 온뒤
4. EmoState handle 로 timestamp, Signal strength, Facial Expression, Mental Command 를 얻어와서 로깅한다.
  - 눈을 깜빡이는지, 좌우 윙크 하는지, 놀라는지 등등 을 알 수 있다는 말인데... 100%는 커녕
    20% 정도라도 동작하면 용서를 해 줄텐데, 전혀 동작하지 않는다. ㅡ.,ㅡ

[컴파일 방법]
$ cmake .
$ make

[실행 방법]
$ ./eslogger log

[결과물]
Start receiving EmoState! Press any key to stop logging...

Time,UserID,Wireless Signal Status,Blink,Wink Left,Wink Right,Surprise,Frown,Smile,Clench,Instantaneous Excitement,Long Term Excitement,Engagement/Boredom,MentalCommand Action,MentalCommand Power,
0,0,2,0,0,0,0,0,0,0,1,0
0.0312769,0,2,0,0,0,0,0,0,0,1,0 user 0 ...
0.531707,0,2,0,0,0,0,0.054799,0,0,1,00 ...
0.672453,0,2,0,0,0,0,0.0541588,0,0,1,0 ...
0.758464,0,2,0,0,0,0,0.053858,0,0,1,00 ...
0.89921,0,2,0,0,0,0,0.0546999,0,0,1,00 ...
1.09469,0,2,0,0,0,0,0.0538765,0,0,1,00 ...
1.1807,0,2,0,0,0,0,0.0621263,0,0,1,0 0 ...
1.32145,0,2,0,0,0,0,0.0672887,0,0,1,00 ...
1.47001,0,2,0,0,0,0,0.0677864,0,0,1,00 ...
1.5873,0,2,0,0,0,0,0.0746682,0,0,1,0 0 ...
1.72805,0,2,0,0,0,0,0.0705324,0,0,1,00 ...
1.87661,0,2,0,0,0,0,0.0575983,0,0,1,00 ...
1.96262,0,2,0,0,0,0,0.0542191,0,0,1,00 ...
2.10337,0,2,0,0,0,0,0.0563959,0,0,1,00 ...
2.21284,0,2,0,0,0,0,0.0597787,0,0,1,00 ...
2.35359,0,2,0,0,0,0,0.0729596,0,0,1,00 ...
2.46305,0,2,0,0,0,0,0.0838853,0,0,1,00 ...
2.61944,0,2,0,0,0,0,0.0795245,0,0,1,00 ...
2.77582,0,2,0,0,0,0,0.0741432,0,0,1,00 ...
2.89311,0,2,0,0,0,0,0.0714714,0,0,1,00 ...
3.01822,0,2,0,0,0,0,0.0638471,0,0,1,00 ...
3.18242,0,2,0,0,0,0,0.0647277,0,0,1,00 ...
3.30753,0,2,0,0,0,0,0.0646014,0,0,1,00 ...
3.43264,0,2,0,0,0,0,0.0591409,0,0,1,00 ...
3.5812,0,2,0,0,0,0,0.0560693,0,0,1,0 0 ...
3.74541,0,2,0,0,0,0,0.0617135,0,0,1,00 ...
3.87051,0,2,0,0,0,0,0.0545445,0,0,1,00 ...
4.01908,0,2,0,0,0,0,0.0549232,0,0,1,00 ...
4.12073,0,2,0,0,0,0,0.0616914,0,0,1,00 ...
4.24584,0,2,0,0,0,0,0.0559444,0,0,1,00 ...
4.37094,0,2,0,0,0,0,0.0707749,0,0,1,00 ...
4.52733,0,2,0,0,0,0,0.0821901,0,0,1,00 ...
4.69935,0,2,0,0,0,0,0.0792065,0,0,1,00 ...
4.82446,0,2,0,0,0,0,0.0866556,0,0,1,00 ...
4.94957,0,2,0,0,0,0,0.0739294,0,0,1,00 ...
5.08249,0,2,0,0,0,0,0.0665007,0,0,1,00 ...

결과물에 무수히 찍혀 있는 '0' 이 값을 제대로 얻어 오지 못하는 것을 보여준다.
값이 들어 오는 것은 Time,UserID,Wireless Signal Status 은 의미가 있어 보이고
정확성이 의심되는 Frown (찡그림?) 값과 주구장창 '1' 만 찍어대는 Mental Command.

백 번 양보해서 Facial Expression 과 Mental Command 는 아직 내용을 살펴 보지 않았기 때문에 뭔가 Training 을 거쳐야지만 제대로 된 값이 들어 온다는 '기대감'을 가져 볼 수 있다고 하더라도 소스코드나 문서 어디에도 (아직 내가 못찾게 숨겨 놨을지도.. ㅡ.ㅡ) 찾아 볼 수 없는 것은
변명할 수 없는 불친절 이라고 밖에...

정리하면,
이 예제는 정상동작하지 않거나 미완성이라고 판단.

댓글 없음: