this code for Kinect camera and i have some error
error LNK2019: unresolved external symbol _imp_NuiCreateSensorByIndex@8 referenced in function "private: bool __thiscall CameraKinect::Init(void)" (?Init@CameraKinect@@AAE_NXZ)
error LNK2019: unresolved external symbol _imp_NuiImageGetColorPixelCoordinatesFromDepthPixel@28 referenced in function "private: bool __thiscall CameraKinect::GetDepthFrame(void)" (?GetDepthFrame@CameraKinect@@AAE_NXZ)
**error LNK1120: 2 unresolved externals
this is Main class
#include <cv.h> #include <highgui.h> #include "../GL/glut.h" #include "Camera_Kinect.h" //color image IplImage* cImg = cvCreateImage(cvSize(COLOR_RES_X, COLOR_RES_Y), IPL_DEPTH_8U, 3); //depth image IplImage* dImg = cvCreateImage(cvSize(DEPTH_RES_X, DEPTH_RES_Y), IPL_DEPTH_8U, 1); //depth image showing only main user IplImage* uImg = cvCreateImage(cvSize(DEPTH_RES_X, DEPTH_RES_Y), IPL_DEPTH_8U, 1); //skeleton Skeleton* skel = new Skeleton(); //the camera class; pointers to the buffers and skeleton are passed in the constructor CameraKinect *camera = new CameraKinect((uchar*)cImg->imageData, (uchar*) dImg->imageData, (uchar*) uImg->imageData, skel); //------------------------------------------------------------------------------------------------------------------- void showImage(char *data, int nwidth, int nheight, int x_start, int x_end, int y_start, int y_end, int nchannels) //------------------------------------------------------------------------------------------------------------------- { //// Create the OpenGL texture map int nTextImageSize = 2048; if(nchannels == 3) { glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, nTextImageSize, nTextImageSize, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, nwidth, nheight,GL_RGB, GL_UNSIGNED_BYTE, data); } else if(nchannels == 4) { glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, nTextImageSize, nTextImageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, nwidth,nheight,GL_RGBA, GL_UNSIGNED_BYTE, data); } else if(nchannels == 1) { glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE, nTextImageSize, nTextImageSize, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, nwidth,nheight,GL_LUMINANCE, GL_UNSIGNED_BYTE, data); } // Display the OpenGL texture map glColor4f(1,1,1,1); glBegin(GL_QUADS); // upper left glTexCoord2f(0, 0); glVertex2f(x_start, y_start); // upper right glTexCoord2f((float)nwidth/(float)nTextImageSize, 0); glVertex2f(x_end, y_start); // bottom right glTexCoord2f((float)nwidth/(float)nTextImageSize, (float)nheight/(float)nTextImageSize); glVertex2f(x_end, y_end); // bottom left glTexCoord2f(0, (float)nheight/(float)nTextImageSize); glVertex2f(x_start, y_end); glEnd(); } //------------------------------------------------------------------------ void glutDisplay (void) //------------------------------------------------------------------------ { //update the buffers passed in constructor camera->Update(); showImage(cImg->imageData, COLOR_RES_X, COLOR_RES_Y, 0, COLOR_RES_X, 0, COLOR_RES_Y, 3); showImage(uImg->imageData, DEPTH_RES_X, DEPTH_RES_Y, 0, DEPTH_RES_X, 0, DEPTH_RES_Y, 1); glutSwapBuffers(); //frame rate camera->GetFrameRate(); } //-------------------------------------------------------------- void glutKeyboard (unsigned char key, int x, int y) //-------------------------------------------------------------- { switch (key) { case 27: { delete camera; exit (1); } } } //---------------------------------------------------------------- void glutIdle (void) //---------------------------------------------------------------- { glutPostRedisplay(); } void fnExit() { delete camera; } //---------------------------------------------------------------- void main(int argc, char* argv[]) //---------------------------------------------------------------- { atexit(fnExit); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(COLOR_RES_X, COLOR_RES_Y); glutCreateWindow ("OpenNI Simple Viewer"); //glutFullScreen(); glutSetCursor(GLUT_CURSOR_NONE); glutKeyboardFunc(glutKeyboard); glutDisplayFunc(glutDisplay); glutIdleFunc(glutIdle); glDisable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Setup the OpenGL viewpoint glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0, COLOR_RES_X, COLOR_RES_Y, 0, -1.0, 1.0); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Per frame code is in glutDisplay glutMainLoop(); }
and this is class Camera_Kinect.cpp
#include "StdAfx.h" //----------------------------------------------------------------------------------------------- CameraKinect::CameraKinect(BYTE *color_buf, BYTE *depth_buf, BYTE *user_buf, Skeleton* skeleton) //------------------------------------------------------------------------------------------------ { //Structures are declared in main code. Here, just pointers are copied. cBuf = color_buf; dBuf = depth_buf; uBuf = user_buf; skel = skeleton; //automatically change the values of depth image resolution based on config.h dImageResX = DEPTH_RES_X; dImageResY = DEPTH_RES_Y; if(dImageResX == 320 && dImageResY == 240) dImageRes = NUI_IMAGE_RESOLUTION_320x240; else if(dImageResX == 640 && dImageResY == 480) dImageRes = NUI_IMAGE_RESOLUTION_640x480; //automatically change the values of color image resolution based on config.h cImageResX = COLOR_RES_X; cImageResY = COLOR_RES_Y; if(cImageResX == 320 && cImageResY == 240) cImageRes = NUI_IMAGE_RESOLUTION_320x240; else if(cImageResX == 640 && cImageResY == 480) cImageRes = NUI_IMAGE_RESOLUTION_640x480; bFoundSkeleton = false; //status of skeleton currentUser = -1; // -1 means no user t_start = GetTickCount(); //for frame rate calculation nFrames = 0; //for frame rate calculation //initialize the camera Init(); } //------------------------------------------------------------------------ CameraKinect::~CameraKinect(void) //------------------------------------------------------------------------- { UnInit(); } void CameraKinect::UnInit( ) { if ( m_pNuiSensor ) { m_pNuiSensor->NuiShutdown( ); m_pNuiSensor->Release(); m_pNuiSensor = NULL; } m_hNextSkeletonEvent = NULL; m_hNextDepthFrameEvent = NULL; m_hNextColorFrameEvent = NULL; } //------------------------------------------------------------------- bool CameraKinect::Init( ) //-------------------------------------------------------------------------- { //create the events. Note that these are optional and NULL pointers can be passed. m_hNextDepthFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); m_hNextColorFrameEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); m_hNextSkeletonEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); HRESULT hr = NuiCreateSensorByIndex(0, &m_pNuiSensor); if ( FAILED( hr ) ) return false; m_instanceId = m_pNuiSensor->NuiDeviceConnectionId(); // initialise the camera DWORD nuiFlags = NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX | NUI_INITIALIZE_FLAG_USES_SKELETON | NUI_INITIALIZE_FLAG_USES_COLOR; hr = m_pNuiSensor->NuiInitialize( nuiFlags ); if ( E_NUI_SKELETAL_ENGINE_BUSY == hr ) { nuiFlags = NUI_INITIALIZE_FLAG_USES_DEPTH | NUI_INITIALIZE_FLAG_USES_COLOR; hr = m_pNuiSensor->NuiInitialize( nuiFlags) ; } if ( FAILED( hr ) ) return false; //Enable Skeleton Tracking //parametes are a handle (set when data is ready) and flags (to control tracking). //Both can be zero if not needed.ameters: if ( HasSkeletalEngine( m_pNuiSensor ) ) { hr = m_pNuiSensor->NuiSkeletonTrackingEnable( m_hNextSkeletonEvent, 0 ); if( FAILED( hr ) ) return false; } //Create a color and a depth stream /*NuiImageStreamOpen has the following parameters: The type of image, which is a value of the NUI_IMAGE_TYPE enumeration. The requested image resolution, which is a value of the NUI_IMAGE_RESOLUTION enumeration. A set of flags that control image preprocessing. If unused, set this to 0. The maximum number of lookahead buffers that the application can hold concurrently. This application uses two buffers so the application can draw with one buffer while capturing data to the other buffer. A handle to an event that the runtime sets when the next frame is available. A location to receive a handle to the open stream.*/ hr = m_pNuiSensor->NuiImageStreamOpen( NUI_IMAGE_TYPE_COLOR, cImageRes, //NUI_IMAGE_RESOLUTION_640x480, 0, 2, m_hNextColorFrameEvent,&m_pVideoStreamHandle ); if( FAILED( hr ) ) return false; hr = m_pNuiSensor->NuiImageStreamOpen( HasSkeletalEngine(m_pNuiSensor) ? NUI_IMAGE_TYPE_DEPTH_AND_PLAYER_INDEX : NUI_IMAGE_TYPE_DEPTH, dImageRes, 0, 2, m_hNextDepthFrameEvent, &m_pDepthStreamHandle ); if( FAILED( hr ) ) return false; return true; } //----------------------------------------------------------------------------------------------- bool CameraKinect::Update() //----------------------------------------------------------------------------------------------- { // There can be two approaches. // First: to capture data when one or all events are triggered. // Second: not to use events and keep getting data in sequence in a loop. This will have high frame rate, // but we cannot be sure if a color and depth image and skeleton are synchronised or are from different view. // this is the first approach. const int numEvents = 3; HANDLE hEvents[numEvents] = { m_hNextDepthFrameEvent, m_hNextColorFrameEvent, m_hNextSkeletonEvent }; int nEventIdx = WaitForMultipleObjects( numEvents, hEvents, TRUE, 100 ); if(nEventIdx == WAIT_TIMEOUT) return false; //once all the events are triggered, we get data sequentially. //if we do not wait for events, frame rate gets double. //if we wait for just one trigger, frame rate is 1.5 times. //some tricks might be played here to increase frame rate without missing a frame. if(GetColorFrame()) if(GetDepthFrame()) GetSkeletonFrame(); return true; } //------------------------------------------------------------------ bool CameraKinect::GetColorFrame() //------------------------------------------------------------------- { HRESULT hr = m_pNuiSensor->NuiImageStreamGetNextFrame( m_pVideoStreamHandle, 0, &cImageFrame ); if ( FAILED( hr ) ) return false; INuiFrameTexture * pTexture = cImageFrame.pFrameTexture; NUI_LOCKED_RECT LockedRect; pTexture->LockRect( 0, &LockedRect, NULL, 0 ); if ( LockedRect.Pitch != 0 ) //pitch is no of bytes in a row { //this needs to be done here and not in main //because when NuiStream is released, the pointer is no more there //cvSetData(iplimg, (byte*) LockedRect.pBits, (iplimg)->widthStep); //memcpy(cBuf, (byte*) LockedRect.pBits, cImageResX * cImageResY * 4); for(int j=0; j<COLOR_RES_Y; j++) for(int i=0; i<COLOR_RES_X; i++) { int k = j*COLOR_RES_X + i; cBuf[3*k] = LockedRect.pBits[4*k+2]; cBuf[3*k+1] = LockedRect.pBits[4*k+1]; cBuf[3*k+2] = LockedRect.pBits[4*k]; } } pTexture->UnlockRect( 0 ); //releasing the stream is a must, otherwise it gives an error m_pNuiSensor->NuiImageStreamReleaseFrame( m_pVideoStreamHandle, &cImageFrame ); return true; } //---------------------------------------------------------------------------- bool CameraKinect::GetDepthFrame( ) //depth image of whole scene and user only are obtained here. //----------------------------------------------------------------------------- { HRESULT hr = m_pNuiSensor->NuiImageStreamGetNextFrame(m_pDepthStreamHandle, 0, &dImageFrame ); if ( FAILED( hr ) ) return false; INuiFrameTexture * pTexture = dImageFrame.pFrameTexture; NUI_LOCKED_RECT LockedRect; pTexture->LockRect( 0, &LockedRect, NULL, 0 ); if ( 0 != LockedRect.Pitch ) //pitch is no of bytes in a row { USHORT* pBuff = (USHORT*) LockedRect.pBits; for(long j=0; j<dImageResY; j++) for(long i=0; i<dImageResX; i++) { long k = j * dImageResX + i; uBuf[k]=0; } for(long j=0; j<dImageResY; j++) for(long i=0; i<dImageResX; i++) { long k = j * dImageResX + i; //first 3 bits have user index in 1-6 range BYTE index = pBuff[k] & 0x07; //shift right to get next 13 bits which have depth USHORT realDepth = (pBuff[k] & 0xFFF8) >> 3; //divide by max and invert color, and set depth buffer in 0-255 range dBuf[k] = 255 - (BYTE)(256*realDepth/0x0fff); //Next we set user buffer. The user pixels get depth value while rest are zero. //The pixels are transformed to align the color image long ii, jj; NuiImageGetColorPixelCoordinatesFromDepthPixel(cImageRes, 0, i, j, realDepth<<3, &ii, &jj); if(ii<0||ii>cImageResX||jj<0||jj>cImageResY) continue; long kk = jj/2 * dImageResX + ii/2; if(index != currentUser+1) uBuf[kk] = 0; else uBuf[kk] = dBuf[k]; } } pTexture->UnlockRect( 0 ); m_pNuiSensor->NuiImageStreamReleaseFrame( m_pDepthStreamHandle, &dImageFrame ); return true; } //----------------------------------------------------------------- bool CameraKinect::GetSkeletonFrame( ) //----------------------------------------------------------------- { HRESULT hr; try{ hr= m_pNuiSensor->NuiSkeletonGetNextFrame( 0, &SkeletonFrame ); } catch(CameraKinect t) { printf("sfsdfhsfsjfsjfhs"); } if ( FAILED( hr ) ) return false; // update current user to one nearest to the camera center float minX = 1000000.0; for( int i = 0 ; i < NUI_SKELETON_COUNT ; i++ ) { if( SkeletonFrame.SkeletonData[i].eTrackingState == NUI_SKELETON_TRACKED || SkeletonFrame.SkeletonData[i].eTrackingState == NUI_SKELETON_POSITION_ONLY) { bFoundSkeleton = true; if(fabs(SkeletonFrame.SkeletonData[i].Position.x)<=minX) { minX=fabs(SkeletonFrame.SkeletonData[i].Position.x); currentUser = i; } } } if(bFoundSkeleton) { // smooth out the skeleton data hr = m_pNuiSensor->NuiTransformSmooth(&SkeletonFrame,NULL); if(FAILED(hr)) return false; //ProcessSkeleton(); UpdateSkeleton(); return true; } else return false; } //---------------------------------------------------------------------------- void CameraKinect::UpdateSkeleton() //---------------------------------------------------------------------------- { //Any required mappings can be made here from Kinect's native skeleton to user defined skeleton. CopySkel(&skel->hipC, NUI_SKELETON_POSITION_HIP_CENTER); CopySkel(&skel->hipL, NUI_SKELETON_POSITION_HIP_LEFT); CopySkel(&skel->hipR, NUI_SKELETON_POSITION_HIP_RIGHT); CopySkel(&skel->shoulderC, NUI_SKELETON_POSITION_SHOULDER_CENTER); CopySkel(&skel->shoulderL, NUI_SKELETON_POSITION_SHOULDER_LEFT); CopySkel(&skel->shoulderR, NUI_SKELETON_POSITION_SHOULDER_RIGHT); // CopySkel(&skel->elbowL, NUI_SKELETON_POSITION_ELBOW_LEFT); // CopySkel(&skel->elbowR, NUI_SKELETON_POSITION_ELBOW_RIGHT); // CopySkel(&skel->handL, NUI_SKELETON_POSITION_HAND_LEFT); // CopySkel(&skel->handR, NUI_SKELETON_POSITION_HAND_RIGHT); // CopySkel(&skel->footL, NUI_SKELETON_POSITION_FOOT_LEFT); // CopySkel(&skel->footR, NUI_SKELETON_POSITION_FOOT_RIGHT); // CopySkel(&skel->ankleL, NUI_SKELETON_POSITION_ANKLE_LEFT); // CopySkel(&skel->ankleR, NUI_SKELETON_POSITION_ANKLE_RIGHT); // CopySkel(&skel->kneeL, NUI_SKELETON_POSITION_KNEE_LEFT); // CopySkel(&skel->kneeR, NUI_SKELETON_POSITION_KNEE_RIGHT); // CopySkel(&skel->wristL, NUI_SKELETON_POSITION_WRIST_LEFT); // CopySkel(&skel->wristR, NUI_SKELETON_POSITION_WRIST_RIGHT); // CopySkel(&skel->head, NUI_SKELETON_POSITION_HEAD); // CopySkel(&skel->spine, NUI_SKELETON_POSITION_SPINE); skel->COM.x = SkeletonFrame.SkeletonData[currentUser].Position.x; skel->COM.y = SkeletonFrame.SkeletonData[currentUser].Position.y; skel->COM.z = SkeletonFrame.SkeletonData[currentUser].Position.z; CameraToImageCoord(&skel->COM, &(SkeletonFrame.SkeletonData[currentUser].Position)); } //---------------------------------------------------------------------------------------------------------- void CameraKinect::CopySkel(vector6 *dst, NUI_SKELETON_POSITION_INDEX idx) //---------------------------------------------------------------------------------------------------------- { //Copy 3D coordinates, 2D coordinates and state. dst->x = SkeletonFrame.SkeletonData[currentUser].SkeletonPositions[idx].x; dst->y = SkeletonFrame.SkeletonData[currentUser].SkeletonPositions[idx].y; dst->z = SkeletonFrame.SkeletonData[currentUser].SkeletonPositions[idx].z; dst->status = SkeletonFrame.SkeletonData[currentUser].eSkeletonPositionTrackingState[idx]; CameraToImageCoord(dst, &(SkeletonFrame.SkeletonData[currentUser].SkeletonPositions[idx])); } //---------------------------------------------------------------------------------------------------------- void CameraKinect::CameraToImageCoord(vector6 *dst, Vector4 *src) //---------------------------------------------------------------------------------------------------------- { float x, y; NuiTransformSkeletonToDepthImage(*src, &x, &y); dst->u = (int) (x+0.5); dst->v = (int) (y+0.5); // adjustment of skeleton for higher resolution depth image if(dImageResX == 640 && dImageResY == 480){ dst->u *= 2; dst->v *= 2;} } //--------------------------------------------------------------------------------------------- void CameraKinect::ProcessSkeleton() //-------------------------------------------------------------------------------------------- { //any smoothing of skeleton will be done here //for example ankle should always be below the knee etc. this can be ensured here. /*Vector4 *ankleL = &(SkeletonFrame.SkeletonData[currentUser].SkeletonPositions[NUI_SKELETON_POSITION_ANKLE_LEFT]); Vector4 *kneeL = &(SkeletonFrame.SkeletonData[currentUser].SkeletonPositions[NUI_SKELETON_POSITION_KNEE_LEFT]); Vector4 *ankleR = &(SkeletonFrame.SkeletonData[currentUser].SkeletonPositions[NUI_SKELETON_POSITION_ANKLE_RIGHT]); Vector4 *kneeR = &(SkeletonFrame.SkeletonData[currentUser].SkeletonPositions[NUI_SKELETON_POSITION_KNEE_RIGHT]);*/ } //--------------------------------------------------------------------------------------------- double CameraKinect::GetFrameRate() //---------------------------------------------------------------------------------------------- { //frame rate can be based on fixed time span or fixed number of frames. //the following code prints once per second nFrames++; DWORD t_end = GetTickCount(); double t_elapsed = t_end - t_start; if(t_elapsed >= 1000) { double fps = (double) nFrames / t_elapsed * 1000; t_start = t_end; nFrames = 0; printf("frame rate is %lg\n", fps); return fps; } return -1; }
please anyone help me