or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

body-part-segmentation.mdindex.mdmodel-loading.mdperson-segmentation.mdrendering-effects.mdutilities.md

utilities.mddocs/

0

# Utility Functions

1

2

Helper functions for pose manipulation, tensor operations, and coordinate transformations. These utilities support advanced use cases and custom processing workflows.

3

4

## Capabilities

5

6

### Pose Manipulation

7

8

Transform and manipulate pose keypoints for different coordinate systems and orientations.

9

10

```typescript { .api }

11

/**

12

* Flips pose keypoints horizontally for mirrored images/videos

13

* @param pose - Input pose to flip

14

* @param imageWidth - Image width for coordinate transformation

15

* @returns New pose with horizontally flipped keypoint coordinates

16

*/

17

function flipPoseHorizontal(pose: Pose, imageWidth: number): Pose;

18

19

interface Pose {

20

/** Array of 17 body keypoints */

21

keypoints: Keypoint[];

22

/** Overall pose confidence score (0-1) */

23

score: number;

24

}

25

26

interface Keypoint {

27

/** Keypoint confidence score (0-1) */

28

score: number;

29

/** Pixel coordinates of the keypoint */

30

position: Vector2D;

31

/** Body part name */

32

part: string;

33

}

34

35

interface Vector2D {

36

x: number;

37

y: number;

38

}

39

```

40

41

### Tensor Operations

42

43

Low-level tensor manipulation functions for custom processing pipelines.

44

45

```typescript { .api }

46

/**

47

* Resizes tensor to target size with padding to maintain aspect ratio

48

* @param imageTensor - Input image tensor (H x W x 3)

49

* @param [targetH, targetW] - Target dimensions

50

* @param flipHorizontal - Flip horizontally during resize

51

* @returns Object with resized tensor and padding information

52

*/

53

function resizeAndPadTo(

54

imageTensor: tf.Tensor3D,

55

[targetH, targetW]: [number, number],

56

flipHorizontal?: boolean

57

): {

58

resizedAndPadded: tf.Tensor3D;

59

paddedBy: [[number, number], [number, number]];

60

};

61

62

/**

63

* Scales and crops tensor back to original input dimensions

64

* @param tensor - Input tensor to transform

65

* @param inputTensorShape - Original input dimensions [height, width]

66

* @param resizedShape - Current tensor dimensions [height, width]

67

* @param padding - Padding amounts from resizeAndPadTo

68

* @param applySigmoidActivation - Apply sigmoid activation function

69

* @returns Scaled and cropped tensor

70

*/

71

function scaleAndCropToInputTensorShape(

72

tensor: tf.Tensor3D,

73

inputTensorShape: [number, number],

74

resizedShape: [number, number],

75

padding: [[number, number], [number, number]],

76

applySigmoidActivation?: boolean

77

): tf.Tensor3D;

78

```

79

80

## Usage Examples

81

82

### Pose Coordinate Transformation

83

84

```typescript

85

import * as bodyPix from '@tensorflow-models/body-pix';

86

87

const net = await bodyPix.load();

88

const video = document.getElementById('webcam'); // 640x480 webcam

89

const canvas = document.getElementById('output');

90

91

// Get segmentation with pose

92

const segmentation = await net.segmentPerson(video, { flipHorizontal: true });

93

94

// Process each detected pose

95

segmentation.allPoses.forEach((pose, index) => {

96

console.log(`Pose ${index} score: ${pose.score}`);

97

98

// Flip pose coordinates back to original orientation if needed

99

const originalPose = bodyPix.flipPoseHorizontal(pose, video.videoWidth);

100

101

// Draw keypoints on canvas

102

drawPoseKeypoints(originalPose, canvas);

103

});

104

105

function drawPoseKeypoints(pose: Pose, canvas: HTMLCanvasElement) {

106

const ctx = canvas.getContext('2d');

107

ctx.fillStyle = 'red';

108

109

pose.keypoints.forEach(keypoint => {

110

if (keypoint.score > 0.5) {

111

ctx.beginPath();

112

ctx.arc(keypoint.position.x, keypoint.position.y, 3, 0, 2 * Math.PI);

113

ctx.fill();

114

}

115

});

116

}

117

```

118

119

### Multiple Pose Transformations

120

121

```typescript

122

// Process multiple people with coordinate transformations

123

const peopleSegmentations = await net.segmentMultiPerson(imageElement);

124

125

const transformedPoses = peopleSegmentations.map(segmentation => {

126

const pose = segmentation.pose;

127

128

// Apply transformations based on your coordinate system

129

const flippedPose = bodyPix.flipPoseHorizontal(pose, imageElement.width);

130

131

// Scale pose to different coordinate system if needed

132

const scaledPose = scalePoseKeypoints(flippedPose, 0.5, 0.5);

133

134

return scaledPose;

135

});

136

137

function scalePoseKeypoints(pose: Pose, scaleX: number, scaleY: number): Pose {

138

return {

139

...pose,

140

keypoints: pose.keypoints.map(keypoint => ({

141

...keypoint,

142

position: {

143

x: keypoint.position.x * scaleX,

144

y: keypoint.position.y * scaleY

145

}

146

}))

147

};

148

}

149

```

150

151

### Custom Tensor Processing

152

153

```typescript

154

import * as tf from '@tensorflow/tfjs-core';

155

156

// Example: Custom preprocessing pipeline

157

async function customImageProcessing(imageElement: HTMLImageElement) {

158

// Convert image to tensor

159

const imageTensor = tf.browser.fromPixels(imageElement);

160

161

// Resize and pad to model input size (513x513 for example)

162

const { resizedAndPadded, paddedBy } = bodyPix.resizeAndPadTo(

163

imageTensor,

164

[513, 513],

165

false

166

);

167

168

// Run your custom processing here

169

const processedTensor = await customModelInference(resizedAndPadded);

170

171

// Scale back to original dimensions

172

const originalSize = bodyPix.scaleAndCropToInputTensorShape(

173

processedTensor,

174

[imageElement.height, imageElement.width],

175

[513, 513],

176

paddedBy,

177

true

178

);

179

180

// Clean up tensors

181

imageTensor.dispose();

182

resizedAndPadded.dispose();

183

processedTensor.dispose();

184

185

return originalSize;

186

}

187

188

async function customModelInference(tensor: tf.Tensor3D): Promise<tf.Tensor3D> {

189

// Your custom model inference logic here

190

// This is just an example - apply your own transformations

191

return tensor.mul(tf.scalar(2.0)); // Example: double the values

192

}

193

```

194

195

### Pose Analysis and Filtering

196

197

```typescript

198

// Filter poses by quality and analyze keypoint visibility

199

function analyzePoses(poses: Pose[]): Pose[] {

200

return poses

201

.filter(pose => pose.score > 0.5) // Only high-confidence poses

202

.map(pose => {

203

// Flip if needed for coordinate system consistency

204

const flippedPose = bodyPix.flipPoseHorizontal(pose, 640);

205

206

// Filter keypoints by confidence

207

const confidentKeypoints = flippedPose.keypoints.filter(

208

keypoint => keypoint.score > 0.3

209

);

210

211

return {

212

...flippedPose,

213

keypoints: confidentKeypoints

214

};

215

});

216

}

217

218

// Usage with segmentation results

219

const segmentation = await net.segmentPerson(videoElement);

220

const qualityPoses = analyzePoses(segmentation.allPoses);

221

222

console.log(`Found ${qualityPoses.length} high-quality poses`);

223

qualityPoses.forEach(pose => {

224

const visibleKeypoints = pose.keypoints.length;

225

console.log(`Pose score: ${pose.score}, visible keypoints: ${visibleKeypoints}`);

226

});

227

```

228

229

### Coordinate System Conversion

230

231

```typescript

232

// Convert between different coordinate systems

233

function convertPoseCoordinates(

234

pose: Pose,

235

fromWidth: number,

236

fromHeight: number,

237

toWidth: number,

238

toHeight: number

239

): Pose {

240

const scaleX = toWidth / fromWidth;

241

const scaleY = toHeight / fromHeight;

242

243

return {

244

...pose,

245

keypoints: pose.keypoints.map(keypoint => ({

246

...keypoint,

247

position: {

248

x: keypoint.position.x * scaleX,

249

y: keypoint.position.y * scaleY

250

}

251

}))

252

};

253

}

254

255

// Example: Convert from video coordinates to canvas coordinates

256

const videoElement = document.getElementById('video'); // 1920x1080

257

const canvasElement = document.getElementById('canvas'); // 640x360

258

259

const segmentation = await net.segmentPerson(videoElement);

260

const canvasPoses = segmentation.allPoses.map(pose =>

261

convertPoseCoordinates(

262

pose,

263

videoElement.videoWidth,

264

videoElement.videoHeight,

265

canvasElement.width,

266

canvasElement.height

267

)

268

);

269

```

270

271

## Advanced Use Cases

272

273

### Custom Image Preprocessing

274

- Resize images while maintaining aspect ratio

275

- Apply custom padding strategies

276

- Implement custom coordinate transformations

277

278

### Pose Data Analysis

279

- Transform poses between coordinate systems

280

- Filter poses by confidence thresholds

281

- Analyze keypoint visibility and quality

282

283

### Multi-Resolution Processing

284

- Process at different resolutions for speed/accuracy trade-offs

285

- Scale results back to original dimensions

286

- Handle aspect ratio preservation

287

288

### Integration with Custom Models

289

- Prepare tensors for custom TensorFlow.js models

290

- Apply consistent preprocessing pipelines

291

- Handle tensor memory management

292

293

## Performance Considerations

294

295

- **Tensor Memory**: Always dispose of tensors when done to prevent memory leaks

296

- **Coordinate Caching**: Cache transformed coordinates when processing video frames

297

- **Batch Processing**: Process multiple poses together when possible

298

- **Async Operations**: Use async/await properly with tensor operations to avoid blocking

299

- **Memory Monitoring**: Monitor GPU memory usage with `tf.memory()` when using many tensor operations