or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

device-management.mdframe-processing.mdindex.mdlogging.mdpipeline-configuration.mdregistration-geometry.md

registration-geometry.mddocs/

0

# Registration and Geometry

1

2

Advanced depth-to-color registration and 3D point cloud generation with camera calibration parameters. This module enables precise alignment between depth and color data and conversion to 3D coordinate systems.

3

4

## Capabilities

5

6

### Registration System

7

8

Main registration class for combining depth and color frames with accurate geometric alignment.

9

10

```java { .api }

11

/**

12

* Combine frames of depth and color camera.

13

*

14

* This class uses a reverse engineered formula that uses factory

15

* preset extrinsic parameters. We do not have a clear understanding of these

16

* particular extrinsic parameters and do not know how to calibrate them by hand.

17

*

18

* If you want to perform registration with standard camera extrinsic matrix,

19

* you probably need something else.

20

*/

21

class Registration {

22

/**

23

* Constructor with camera parameters

24

* @param depth_p Depth camera parameters (can use factory values or custom)

25

* @param rgb_p Color camera parameters (recommend using factory values)

26

*/

27

Registration(@ByVal Freenect2Device.IrCameraParams depth_p,

28

@ByVal Freenect2Device.ColorCameraParams rgb_p);

29

30

/**

31

* Undistort and register a single depth point to color camera

32

* @param dx Distorted depth coordinate x (pixel)

33

* @param dy Distorted depth coordinate y (pixel)

34

* @param dz Depth value (millimeter)

35

* @param cx Output: Undistorted color coordinate x (normalized)

36

* @param cy Output: Undistorted color coordinate y (normalized)

37

*/

38

void apply(int dx, int dy, float dz, @ByRef FloatPointer cx, @ByRef FloatPointer cy);

39

void apply(int dx, int dy, float dz, @ByRef FloatBuffer cx, @ByRef FloatBuffer cy);

40

void apply(int dx, int dy, float dz, @ByRef float[] cx, @ByRef float[] cy);

41

42

/**

43

* Map color images onto depth images (full registration)

44

* @param rgb Color image (1920x1080 BGRX)

45

* @param depth Depth image (512x424 float)

46

* @param undistorted Output: Undistorted depth image

47

* @param registered Output: Color image for the depth image (512x424)

48

*/

49

void apply(@Const Frame rgb, @Const Frame depth, Frame undistorted, Frame registered);

50

51

/**

52

* Full registration with additional options

53

* @param rgb Color image (1920x1080 BGRX)

54

* @param depth Depth image (512x424 float)

55

* @param undistorted Output: Undistorted depth image

56

* @param registered Output: Color image for depth image (512x424)

57

* @param enable_filter Filter out pixels not visible to both cameras

58

* @param bigdepth Output: Mapping of depth onto colors (1920x1082 float, optional)

59

* @param color_depth_map Output: Index of mapped color pixel for each depth pixel (optional)

60

*/

61

void apply(@Const Frame rgb, @Const Frame depth, Frame undistorted, Frame registered,

62

@Cast("const bool") boolean enable_filter, Frame bigdepth, IntPointer color_depth_map);

63

void apply(@Const Frame rgb, @Const Frame depth, Frame undistorted, Frame registered,

64

@Cast("const bool") boolean enable_filter, Frame bigdepth, IntBuffer color_depth_map);

65

void apply(@Const Frame rgb, @Const Frame depth, Frame undistorted, Frame registered,

66

@Cast("const bool") boolean enable_filter, Frame bigdepth, int[] color_depth_map);

67

68

/**

69

* Undistort depth image only

70

* @param depth Depth image (512x424 float)

71

* @param undistorted Output: Undistorted depth image

72

*/

73

void undistortDepth(@Const Frame depth, Frame undistorted);

74

75

/**

76

* Construct a 3-D point with color in a point cloud

77

* @param undistorted Undistorted depth frame from apply()

78

* @param registered Registered color frame from apply()

79

* @param r Row (y) index in depth image

80

* @param c Column (x) index in depth image

81

* @param x Output: X coordinate of the 3-D point (meter)

82

* @param y Output: Y coordinate of the 3-D point (meter)

83

* @param z Output: Z coordinate of the 3-D point (meter)

84

* @param rgb Output: Color of the 3-D point (BGRX format)

85

*/

86

void getPointXYZRGB(@Const Frame undistorted, @Const Frame registered, int r, int c,

87

@ByRef FloatPointer x, @ByRef FloatPointer y, @ByRef FloatPointer z, @ByRef FloatPointer rgb);

88

void getPointXYZRGB(@Const Frame undistorted, @Const Frame registered, int r, int c,

89

@ByRef FloatBuffer x, @ByRef FloatBuffer y, @ByRef FloatBuffer z, @ByRef FloatBuffer rgb);

90

void getPointXYZRGB(@Const Frame undistorted, @Const Frame registered, int r, int c,

91

@ByRef float[] x, @ByRef float[] y, @ByRef float[] z, @ByRef float[] rgb);

92

93

/**

94

* Construct a 3-D point in a point cloud (without color)

95

* @param undistorted Undistorted depth frame from apply()

96

* @param r Row (y) index in depth image

97

* @param c Column (x) index in depth image

98

* @param x Output: X coordinate of the 3-D point (meter)

99

* @param y Output: Y coordinate of the 3-D point (meter)

100

* @param z Output: Z coordinate of the 3-D point (meter)

101

*/

102

void getPointXYZ(@Const Frame undistorted, int r, int c,

103

@ByRef FloatPointer x, @ByRef FloatPointer y, @ByRef FloatPointer z);

104

void getPointXYZ(@Const Frame undistorted, int r, int c,

105

@ByRef FloatBuffer x, @ByRef FloatBuffer y, @ByRef FloatBuffer z);

106

void getPointXYZ(@Const Frame undistorted, int r, int c,

107

@ByRef float[] x, @ByRef float[] y, @ByRef float[] z);

108

}

109

```

110

111

**Usage Examples:**

112

113

```java

114

// Initialize registration with device parameters

115

Freenect2Device.IrCameraParams irParams = device.getIrCameraParams();

116

Freenect2Device.ColorCameraParams colorParams = device.getColorCameraParams();

117

Registration registration = new Registration(irParams, colorParams);

118

119

// Capture synchronized frames

120

FrameMap frames = new FrameMap();

121

if (listener.waitForNewFrame(frames, 10000)) {

122

Frame color = frames.get(Frame.Color);

123

Frame depth = frames.get(Frame.Depth);

124

125

// Create output frames

126

Frame undistorted = new Frame(512, 424, 4); // float depth

127

Frame registered = new Frame(512, 424, 4); // BGRX color

128

129

// Perform registration

130

registration.apply(color, depth, undistorted, registered);

131

132

System.out.println("Registration complete");

133

134

listener.release(frames);

135

}

136

137

// Single point registration

138

float[] cx = new float[1];

139

float[] cy = new float[1];

140

registration.apply(256, 212, 1000.0f, cx, cy); // Center pixel at 1m depth

141

System.out.println("Depth point maps to color coordinates: " + cx[0] + ", " + cy[0]);

142

```

143

144

### Point Cloud Generation

145

146

Generate 3D point clouds from registered depth and color data.

147

148

**Usage Examples:**

149

150

```java

151

// Generate point cloud from registered frames

152

Frame undistorted = new Frame(512, 424, 4);

153

Frame registered = new Frame(512, 424, 4);

154

registration.apply(color, depth, undistorted, registered);

155

156

// Create point cloud data structures

157

int width = (int)undistorted.width();

158

int height = (int)undistorted.height();

159

float[] pointCloud = new float[width * height * 3]; // x,y,z per point

160

int[] colorData = new int[width * height]; // BGRX per point

161

162

// Extract point cloud

163

float[] x = new float[1], y = new float[1], z = new float[1];

164

float[] rgb = new float[1];

165

166

int pointIndex = 0;

167

for (int r = 0; r < height; r++) {

168

for (int c = 0; c < width; c++) {

169

registration.getPointXYZRGB(undistorted, registered, r, c, x, y, z, rgb);

170

171

// Store 3D coordinates (in meters)

172

pointCloud[pointIndex * 3] = x[0];

173

pointCloud[pointIndex * 3 + 1] = y[0];

174

pointCloud[pointIndex * 3 + 2] = z[0];

175

176

// Store color (unpack BGRX)

177

int rgbInt = Float.floatToIntBits(rgb[0]);

178

colorData[pointIndex] = rgbInt;

179

180

pointIndex++;

181

}

182

}

183

184

// Filter valid points (remove NaN and infinite values)

185

List<float[]> validPoints = new ArrayList<>();

186

List<Integer> validColors = new ArrayList<>();

187

188

for (int i = 0; i < pointIndex; i++) {

189

float px = pointCloud[i * 3];

190

float py = pointCloud[i * 3 + 1];

191

float pz = pointCloud[i * 3 + 2];

192

193

if (Float.isFinite(px) && Float.isFinite(py) && Float.isFinite(pz) && pz > 0) {

194

validPoints.add(new float[]{px, py, pz});

195

validColors.add(colorData[i]);

196

}

197

}

198

199

System.out.println("Generated " + validPoints.size() + " valid 3D points");

200

```

201

202

### Advanced Registration Options

203

204

```java

205

// Full registration with filtering and additional outputs

206

Frame bigdepth = new Frame(1920, 1082, 4); // Note: 1082 not 1080

207

int[] colorDepthMap = new int[512 * 424];

208

209

registration.apply(

210

color, depth, // Input frames

211

undistorted, registered, // Standard outputs

212

true, // Enable filtering

213

bigdepth, // Depth mapped to color resolution

214

colorDepthMap // Per-depth-pixel color mapping

215

);

216

217

// Process big depth image (depth data at color resolution)

218

System.out.println("Big depth dimensions: " + bigdepth.width() + "x" + bigdepth.height());

219

220

// Use color-depth mapping for efficient lookups

221

BytePointer colorData = registered.data();

222

for (int depthPixel = 0; depthPixel < colorDepthMap.length; depthPixel++) {

223

int colorPixel = colorDepthMap[depthPixel];

224

if (colorPixel >= 0) {

225

// Valid mapping from depth pixel to color pixel

226

int colorOffset = colorPixel * 4; // BGRX format

227

// Access color data at colorData + colorOffset

228

}

229

}

230

```

231

232

### Registration Implementation

233

234

Internal registration implementation details.

235

236

```java { .api }

237

/**

238

* Implementation details for registration

239

*/

240

class RegistrationImpl {

241

// Internal implementation - not for direct use

242

}

243

```

244

245

## Coordinate Systems and Calibration

246

247

### Understanding Coordinate Systems

248

249

The Kinect v2 uses different coordinate systems for depth and color cameras:

250

251

- **Depth Camera**: 512x424 resolution, centered coordinate system

252

- **Color Camera**: 1920x1080 resolution, different intrinsic parameters

253

- **3D World**: Metric coordinates in meters, origin at depth camera

254

255

### Calibration Parameter Usage

256

257

```java

258

// Examine factory calibration parameters

259

Freenect2Device.IrCameraParams irParams = device.getIrCameraParams();

260

System.out.println("IR Camera Intrinsics:");

261

System.out.println(" fx: " + irParams.fx() + ", fy: " + irParams.fy());

262

System.out.println(" cx: " + irParams.cx() + ", cy: " + irParams.cy());

263

System.out.println(" Distortion - k1: " + irParams.k1() + ", k2: " + irParams.k2());

264

265

Freenect2Device.ColorCameraParams colorParams = device.getColorCameraParams();

266

System.out.println("Color Camera Intrinsics:");

267

System.out.println(" fx: " + colorParams.fx() + ", fy: " + colorParams.fy());

268

System.out.println(" cx: " + colorParams.cx() + ", cy: " + colorParams.cy());

269

System.out.println(" Extrinsic shift: " + colorParams.shift_d() + ", " + colorParams.shift_m());

270

271

// Use custom calibrated parameters (advanced users)

272

irParams.fx(365.456f); // Custom focal length

273

irParams.fy(365.456f);

274

irParams.cx(257.608f); // Custom principal point

275

irParams.cy(210.040f);

276

device.setIrCameraParams(irParams);

277

278

// Create registration with custom parameters

279

Registration customRegistration = new Registration(irParams, colorParams);

280

```

281

282

### Color Data Format

283

284

When extracting color from point clouds, the RGB data is packed in BGRX format:

285

286

```java

287

// Unpack BGRX color data

288

float[] rgbFloat = new float[1];

289

registration.getPointXYZRGB(undistorted, registered, r, c, x, y, z, rgbFloat);

290

291

int rgbPacked = Float.floatToIntBits(rgbFloat[0]);

292

int blue = rgbPacked & 0xFF;

293

int green = (rgbPacked >> 8) & 0xFF;

294

int red = (rgbPacked >> 16) & 0xFF;

295

// Alpha/unused byte is (rgbPacked >> 24) & 0xFF

296

297

System.out.println("Point color - R: " + red + ", G: " + green + ", B: " + blue);

298

```