Subversion Repositories Code-Repo

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
287 Kevin 1
#include "OpenNI.h"
2
 
3
#define CHECK_RC(rc, what)										\
4
if (rc != XN_STATUS_OK) {										\
5
	QString error = QString(QString(what) + "failed: ");		\
6
	error += QString(xnGetStatusString(rc));					\
7
	emit setStatusString(error);								\
8
	exit(rc);													\
9
	return;														\
10
}
11
 
12
using namespace xn;
13
 
14
extern QSemaphore processorBuffer;
15
 
16
XnBool OpenNI::fileExists(const char *fn) {
17
	XnBool exists;
18
	xnOSDoesFileExist(fn, &exists);
19
	return exists;
20
}
21
 
22
OpenNI::OpenNI(QObject *parent)
23
: QThread(parent) {
24
 
25
	moveToThread(this);
26
}
27
 
28
OpenNI::~OpenNI() {
29
 
30
}
31
 
32
void OpenNI::run() {
33
 
34
	XnStatus nRetVal = XN_STATUS_OK;
35
	Context context;
36
	ScriptNode scriptNode;
37
	EnumerationErrors errors;
38
 
39
	// Check if the config file exists
40
	const char *fn = NULL;
289 Kevin 41
	if (fileExists(CONFIG_XML_PATH)) fn = CONFIG_XML_PATH;
42
	else if (fileExists(CONFIG_XML_PATH_LOCAL)) fn = CONFIG_XML_PATH_LOCAL;
287 Kevin 43
	else {
289 Kevin 44
		QString error = QString("Could not find " + QString(CONFIG_XML_PATH) + " nor " + QString(CONFIG_XML_PATH_LOCAL));
287 Kevin 45
		emit setStatusString(error);
46
		exit(XN_STATUS_ERROR);
47
		return;
48
	}
49
	// Load the config file
50
	nRetVal = context.InitFromXmlFile(fn, scriptNode, &errors);
51
 
52
	// Check to see if a sensor is connected
53
	if (nRetVal == XN_STATUS_NO_NODE_PRESENT) {
54
		XnChar strError[1024];
55
		errors.ToString(strError, 1024);
56
		emit setStatusString(QString(strError));
57
		exit(nRetVal);
58
		return;
59
	} else if (nRetVal != XN_STATUS_OK) {
60
		QString error = QString("Open failed: " + QString(xnGetStatusString(nRetVal)));
61
		emit setStatusString(error);
62
		exit(nRetVal);
63
		return;
64
	}
65
 
66
	// Connect to the attached sensor
67
	DepthGenerator depth;
68
	nRetVal = context.FindExistingNode(XN_NODE_TYPE_DEPTH, depth);
69
	CHECK_RC(nRetVal, "Find depth generator");
70
 
71
	// Pull FPS and depth data
72
	XnFPSData xnFPS;
73
	nRetVal = xnFPSInit(&xnFPS, 180);
74
	CHECK_RC(nRetVal, "FPS Init");
75
 
76
	DepthMetaData depthMD;
77
 
78
	short min = 9999, max = 0;
79
 
80
	// If this point is reached, notify that the sensor is ready
81
	emit sensorConnected();
82
 
83
	while (1) {
84
		// Ensure that the processing queue isnt too long
85
		processorBuffer.acquire(1);
86
 
87
		// Wait for an updated frame from the sensor
88
		nRetVal = context.WaitOneUpdateAll(depth);
89
		if (nRetVal != XN_STATUS_OK) {
90
			QString error = QString("UpdateData failed: " + QString(xnGetStatusString(nRetVal)));
91
			emit setStatusString(error);
92
			break;
93
		}
94
 
95
		// Mark the frame (for determining FPS)
96
		xnFPSMarkFrame(&xnFPS);
97
 
98
		// Grab the depth data
99
		depth.GetMetaData(depthMD);
100
 
101
		// Grab the size and FOV of the sensor
102
		int X = depthMD.XRes();
103
		int Y = depthMD.YRes();
104
 
105
		XnFieldOfView fov;
106
		depth.GetFieldOfView(fov);
107
 
108
		emit setFOV(fov.fHFOV, fov.fVFOV);
109
 
110
		// Show the size/FOV/FPS/frame
111
		QString status = "Res: " + QString::number(X) + " x " + QString::number(Y);
112
		//status += " / FoV (rad): " + QString::number(fov.fHFOV) + " (H) " + QString::number(fov.fVFOV) + " (V)";
113
		min = qMin(min, (short)depthMD(depthMD.XRes() / 2, depthMD.YRes() / 2));
114
		max = qMax(max, (short)depthMD(depthMD.XRes() / 2, depthMD.YRes() / 2));
115
 
116
		status += " / Center: " + QString::number(depthMD(depthMD.XRes() / 2, depthMD.YRes() / 2));
117
		status += " / Min: " + QString::number(min) + " / Max: " + QString::number(max);
118
		emit setStatusString(status);
119
		emit setFPSString(QString::number(xnFPSCalc(&xnFPS)));
120
		emit setFrameString(QString::number(depthMD.FrameID()));
121
 
122
		// Allocate a new cv::Mat
289 Kevin 123
		cv::Mat depthData = cv::Mat(Y_RES, X_RES, CV_16UC1);
287 Kevin 124
 
125
		// Save the depth data (mirrored horizontally)
126
		ushort *p;
127
		for (int y = 0; y < Y; ++y) {
128
			p = depthData.ptr<ushort>(y);
129
			for (int x = 0; x < X; ++x) {
130
				short pixel = depthMD.Data()[(y * X) + (X - x - 1)];
131
				p[x] = pixel;
132
			}
133
		}
134
 
135
		// Send the depth data for processing
136
		emit processDepthData(depthData);
137
	}
138
 
139
	depth.Release();
140
	scriptNode.Release();
141
	context.Release();
142
}