00001
00002 #include "WinBaseLib.h"
00003
00004 #include "KinectFaceTracker.h"
00005 #include "NiDevice.h"
00006 #include "Graph.h"
00007
00008
00009 #ifdef ENABLE_KINECT_SDK
00010
00011 using namespace jbxl;
00012 using namespace jbxwl;
00013
00014
00016
00017
00018 CKinectFaceTracker::CKinectFaceTracker(void)
00019 {
00020 is_detected = FALSE;
00021
00022 m_image = NULL;
00023 m_depth = NULL;
00024
00025 m_tracker = NULL;
00026 m_image_data = NULL;
00027 m_depth_data = NULL;
00028 m_result = NULL;
00029 }
00030
00031
00032
00033 void CKinectFaceTracker::free(void)
00034 {
00035
00036 if (m_result!=NULL) {
00037 m_result->Release();
00038 m_result = NULL;
00039 }
00040
00041 if (m_image_data!=NULL) {
00042 m_image_data->Release();
00043 m_image_data = NULL;
00044 }
00045
00046 if (m_depth_data!=NULL) {
00047 m_depth_data->Release();
00048 m_depth_data = NULL;
00049 }
00050
00051 if (m_tracker!=NULL) {
00052 m_tracker->Release();
00053 m_tracker = NULL;
00054 }
00055 }
00056
00057
00058
00059 BOOL CKinectFaceTracker::create(int width, int height, uByte* image, uByte* depth)
00060 {
00061 if (image==NULL || depth==NULL) return FALSE;
00062
00063 m_tracker = FTCreateFaceTracker();
00064 if (m_tracker==NULL) return FALSE;
00065
00066
00067 FT_CAMERA_CONFIG image_config;
00068 FT_CAMERA_CONFIG depth_config;
00069
00070 image_config.Width = width;
00071 image_config.Height = height;
00072 image_config.FocalLength = NUI_CAMERA_COLOR_NOMINAL_FOCAL_LENGTH_IN_PIXELS*(width/640.0f);
00073
00074 depth_config.Width = width;
00075 depth_config.Height = height;
00076 depth_config.FocalLength = NUI_CAMERA_DEPTH_NOMINAL_FOCAL_LENGTH_IN_PIXELS*(width/320.0f);
00077
00078 HRESULT hr = m_tracker->Initialize(&image_config, &depth_config, NULL, NULL);
00079 if (FAILED(hr)) {
00080
00081 free();
00082 return FALSE;
00083 }
00084
00085 hr = m_tracker->CreateFTResult(&m_result);
00086 if (FAILED(hr)) {
00087 free();
00088 return FALSE;
00089 }
00090
00091 m_image_data = FTCreateImage();
00092 m_depth_data = FTCreateImage();
00093 if (!m_image_data || !m_depth_data) {
00094 free();
00095 return FALSE;
00096 }
00097
00098 m_image_data->Attach(width, height, image, FTIMAGEFORMAT_UINT8_B8G8R8X8, width*4);
00099 m_depth_data->Attach(width, height, depth, FTIMAGEFORMAT_UINT16_D13P3, width*2);
00100
00101
00102 m_sensor.pVideoFrame = m_image_data;
00103 m_sensor.pDepthFrame = m_depth_data;
00104 m_sensor.ZoomFactor = 1.0f;
00105 m_sensor.ViewOffset.x = 0;
00106 m_sensor.ViewOffset.y = 0;
00107
00108 return TRUE;
00109 }
00110
00111
00112
00113 BOOL CKinectFaceTracker::detect(FT_VECTOR3D* hint)
00114 {
00115 if (m_tracker==NULL) return FALSE;
00116
00117 if (is_detected) {
00118 HRESULT hr = m_tracker->ContinueTracking(&m_sensor, hint, m_result);
00119 if (FAILED(hr) || FAILED(m_result->GetStatus())) is_detected = FALSE;
00120 }
00121
00122 else {
00123 HRESULT hr = m_tracker->StartTracking(&m_sensor, NULL, hint, m_result);
00124 if (SUCCEEDED(hr) && SUCCEEDED(m_result->GetStatus())) is_detected = TRUE;
00125 }
00126
00127 return is_detected;
00128 }
00129
00130
00131
00132 RECT CKinectFaceTracker::getFaceRect(void)
00133 {
00134 RECT rect;
00135
00136 this->m_result->GetFaceRect(&rect);
00137 return rect;
00138 }
00139
00140
00141
00142 Vector<float> CKinectFaceTracker::getFaceEulerXYZ(void)
00143 {
00144 Vector<float> eul(0.0, 0.0, 0.0, 0.0, -1.0);
00145
00146 FLOAT scale;
00147 FLOAT rotXYZ[3];
00148 FLOAT posXYZ[3];
00149
00150 HRESULT hr = m_result->Get3DPose(&scale, rotXYZ, posXYZ);
00151 if (FAILED(hr)) return eul;
00152
00153 eul.set((float)(rotXYZ[0]*DEGREE2RAD), (float)(rotXYZ[1]*DEGREE2RAD), (float)(rotXYZ[2]*DEGREE2RAD));
00154
00155 return eul;
00156 }
00157
00158
00159
00160 void CKinectFaceTracker::drawFaceRect(ExCmnHead* viewdata, int scale, BOOL mirror, int col, int line)
00161 {
00162 if (is_detected && viewdata!=NULL) {
00163
00164 MSGraph<unsigned int> vp;
00165 vp.xs = viewdata->xsize;
00166 vp.ys = viewdata->ysize;
00167 vp.zs = 1;
00168 vp.gp = (unsigned int*)viewdata->grptr;
00169
00170 RECT rect = getFaceRect();
00171 int xs, xe, ys, ye;
00172 ys = rect.top/scale;
00173 ye = rect.bottom/scale;
00174
00175 if (scale<=0) scale = 1;
00176 if (mirror) {
00177 xs = rect.left/scale;
00178 xe = rect.right/scale;
00179 }
00180 else {
00181 xs = vp.xs - rect.left/scale - 1;
00182 xe = vp.xs - rect.right/scale - 1;
00183 }
00184
00185 MSGraph_Box(vp, xs, ys, xe, ye, col);
00186 for (int i=1; i<line; i++) {
00187 MSGraph_Box(vp, xs-i, ys-i, xe+i, ye+i, col);
00188 MSGraph_Box(vp, xs+i, ys+i, xe-i, ye-i, col);
00189 }
00190 }
00191 }
00192
00193
00194 #endif // ENABLE_KINECT_SDK
00195