Quantcast
Channel: Visual C forum
Viewing all articles
Browse latest Browse all 15302

problem in code c++ about Kinect Camera

$
0
0

this code for Kinect camera and i have some error

  1. error LNK2019: unresolved external symbol _imp_NuiCreateSensorByIndex@8 referenced in function "private: bool __thiscall CameraKinect::Init(void)" (?Init@CameraKinect@@AAE_NXZ)

  2. error LNK2019: unresolved external symbol _imp_NuiImageGetColorPixelCoordinatesFromDepthPixel@28 referenced in function "private: bool __thiscall CameraKinect::GetDepthFrame(void)" (?GetDepthFrame@CameraKinect@@AAE_NXZ)

  3. **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 


Viewing all articles
Browse latest Browse all 15302

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>