Tizen 2.1 base
[apps/native/sample/FaceTracker.git] / project / src / FaceThread.cpp
1 //
2 // Tizen C++ SDK
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.tizenopensource.org/license
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include "FaceThread.h"
19
20 #define SAFE_DELETE(x)  if (x) { delete x; x = null; }
21
22 using namespace Tizen::Base;
23 using namespace Tizen::Base::Collection;
24 using namespace Tizen::Base::Runtime;
25 using namespace Tizen::Graphics;
26 using namespace Tizen::Uix::Vision;
27 using namespace Tizen::Ui::Controls;
28
29 static const int PREVIEW_WIDTH = 320;
30 static const int PREVIEW_HEIGHT = 240;
31
32
33 FaceThread::FaceThread(void)
34         : __pFaceDetector(null)
35         , __pFaceReconizer(null)
36         , __pFInfoReference(null)
37         , __pFaceComponents(null)
38         , __pFaceRect(new Rectangle(0,0,0,0))
39         , __pFaceData(null)
40         , __pPrevFaceBuffer(null)
41         , __pCurFaceBuffer(null)
42 {
43 }
44
45 FaceThread::~FaceThread(void)
46 {
47         SAFE_DELETE(__pFaceRect);
48         SAFE_DELETE(__pFaceComponents);
49         SAFE_DELETE(__pPrevFaceBuffer);
50         SAFE_DELETE(__pCurFaceBuffer);
51 }
52
53 result
54 FaceThread::Construct(void)
55 {
56         Thread::Construct(THREAD_TYPE_EVENT_DRIVEN);
57         return E_SUCCESS;
58 }
59
60 bool
61 FaceThread::OnStart(void)
62 {
63         return true;
64 }
65
66 void
67 FaceThread::OnStop(void)
68 {
69         return;
70 }
71
72 void
73 FaceThread::SetFaceDetectData(FaceDetector *pFD, FaceRecognizer *pFR, FaceRecognitionInfo *pFI, FaceData *pFaceData,  Form* pForm)
74 {
75         __pFaceDetector = pFD;
76         __pFaceReconizer = pFR;
77         __pFInfoReference = pFI;
78         __pFaceData = pFaceData;
79         __pFaceTrackerForm = pForm;
80
81         return;
82 }
83
84 void
85 FaceThread::OnUserEventReceivedN (RequestId requestId, Tizen::Base::Collection::IList *pArgs)
86 {
87         __pFaceData->SetThreadCompleted(false);
88
89         ArrayList* pList = (Tizen::Base::Collection::ArrayList*)pArgs;
90         ByteBuffer* pCurBuffer = (ByteBuffer*)pList->GetAt(0);
91
92         __pCurFaceBuffer = __pFaceDetector->PreprocessDataN(*pCurBuffer, Dimension(PREVIEW_WIDTH, PREVIEW_HEIGHT), PIXEL_FORMAT_YCbCr420_PLANAR);
93
94         pList->RemoveAll();
95         SAFE_DELETE(pList);
96         SAFE_DELETE(pCurBuffer);
97
98         TryReturn(__pCurFaceBuffer != null, , "Failed to create FaceBuffer");
99
100         static int frameCnt = 20;
101         static int similarity = 0;
102         static RunMode runMode = RUN_MODE_FACE_DETECTION;
103         
104         switch(runMode)
105         {
106         case RUN_MODE_FACE_DETECTION:
107         {
108                 IList *pFaceDetectList = __pFaceDetector->DetectFacesN(*__pCurFaceBuffer);
109                 if (pFaceDetectList != null)
110                 {
111                         if (pFaceDetectList->GetCount() > 0)
112                         {
113                                 Rectangle* pFaceRect = (Tizen::Graphics::Rectangle*)pFaceDetectList->GetAt(0);
114                                 __pFaceRect->SetBounds(pFaceRect->x , pFaceRect->y , pFaceRect->width,pFaceRect->height);
115
116                                 pFaceDetectList->RemoveAll(true);
117                                 __pFaceData->SetFaceDetected(true);
118                         }
119                         else
120                         {
121                                 __pFaceData->SetFaceDetected(false);
122                         }
123
124                         SAFE_DELETE(pFaceDetectList);
125                 }
126                 if (__pFaceData->GetFaceDetected() == false)
127                 {
128                         break;
129                 }
130                 __pFaceComponents = __pFaceDetector->ExtractFaceComponentsN(*__pCurFaceBuffer, *__pFaceRect);
131                 if (__pFaceComponents == null)
132                 {
133                         break;
134                 }
135                 ByteBuffer*  pFeatureBuffer =  __pFaceReconizer->ExtractFeatureN(*__pCurFaceBuffer,*__pFaceComponents);
136                 if (pFeatureBuffer != null)
137                 {
138                         FaceRecognitionInfo *pFInfoCurrent = new FaceRecognitionInfo();
139                         if (pFInfoCurrent != null)
140                         {
141                                 result r = pFInfoCurrent->Construct(*pFeatureBuffer);
142                                 if (r == E_SUCCESS)
143                                 {
144                                         similarity = __pFaceReconizer->MeasureSimilarity(*__pFInfoReference, *pFInfoCurrent);
145                                 }
146                         }
147                         SAFE_DELETE(pFInfoCurrent);
148                         SAFE_DELETE(pFeatureBuffer);
149
150                         runMode = RUN_MODE_FACE_TRACKING;
151                 }
152                 else
153                 {
154                         runMode = RUN_MODE_FACE_DETECTION;
155                 }
156                 SAFE_DELETE(__pFaceComponents);
157                 break;
158         }
159         case RUN_MODE_FACE_TRACKING:
160         {
161                 frameCnt--;
162                 if (frameCnt == 0)
163                 {
164                         runMode = RUN_MODE_FACE_DETECTION;
165                         frameCnt = 20;
166                 }
167                 int xDiff = 0;
168                 int yDiff = 0;
169                 if(E_SUCCESS == __pFaceDetector->GetFaceMovement(*__pPrevFaceBuffer, *__pCurFaceBuffer, *__pFaceRect, xDiff , yDiff))
170                 {
171                         __pFaceData->SetFaceDetected(true);
172                         __pFaceRect->x += xDiff;
173                         __pFaceRect->y += yDiff;
174                 }
175                 else
176                 {
177                         __pFaceData->SetFaceDetected(false);
178                         runMode = RUN_MODE_FACE_DETECTION;
179                         frameCnt = 20;
180                 }
181                 SAFE_DELETE(__pPrevFaceBuffer);
182                 break;
183         }
184         default:
185                 break;
186         }
187
188         if(runMode == RUN_MODE_FACE_TRACKING)
189         {
190                 __pPrevFaceBuffer = __pCurFaceBuffer;
191                 __pCurFaceBuffer = null;
192         }
193         else
194         {
195                 SAFE_DELETE(__pCurFaceBuffer);
196         }
197
198         __pFaceData->SetRectangle(*__pFaceRect);
199         __pFaceData->SetSimilarity(similarity);
200
201         __pFaceTrackerForm->SendUserEvent(RUN_MODE_FACE_DETECTION, null);
202         __pFaceData->SetThreadCompleted(true);
203
204         return;
205 }