@eyepop.ai/eyepop-render-2d 3.18.0 → 3.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/eyepop.render2d.index.d.mts +25 -1
- package/dist/eyepop.render2d.index.d.ts +25 -1
- package/dist/eyepop.render2d.index.js +121 -0
- package/dist/eyepop.render2d.index.js.map +1 -1
- package/dist/eyepop.render2d.index.mjs +120 -0
- package/dist/eyepop.render2d.index.mjs.map +1 -1
- package/dist/eyepop.render2d.min.js +1 -1
- package/package.json +3 -4
package/README.md
CHANGED
|
@@ -219,6 +219,20 @@ Render2d.renderContour({
|
|
|
219
219
|
})
|
|
220
220
|
```
|
|
221
221
|
|
|
222
|
+
#### Render Depth Maps
|
|
223
|
+
|
|
224
|
+
Renders the frame-level depth map produced by depth estimation abilities (e.g. `eyepop.depth.*`)
|
|
225
|
+
as a turbo-colormap heatmap blended over the frame: near = warm (red/yellow), far = cool (blue).
|
|
226
|
+
Sky pixels (+Infinity) leave the frame untouched unless `renderSky` is set.
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
Render2d.renderDepth({
|
|
230
|
+
target: '$',
|
|
231
|
+
opacity: 0.5, // overlay opacity over the underlying frame
|
|
232
|
+
renderSky: false, // also paint sky pixels
|
|
233
|
+
})
|
|
234
|
+
```
|
|
235
|
+
|
|
222
236
|
#### Blur an Object
|
|
223
237
|
|
|
224
238
|
```typescript
|
|
@@ -220,6 +220,29 @@ declare class RenderClasses implements Render {
|
|
|
220
220
|
drawLabel(label: string, context: CanvasRenderingContext2D, xOffset: number, yOffset: number, style: Style, drawDisabled: boolean, xPadding: number, yPadding: number, labelWidth: number, labelHeight: number, borderRadius: number): void;
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
type RenderDepthOptions = {
|
|
224
|
+
opacity?: number;
|
|
225
|
+
renderSky?: boolean;
|
|
226
|
+
} & RenderTarget;
|
|
227
|
+
/**
|
|
228
|
+
* Renders a frame-level depth map (Prediction.depth) as a turbo-colormap
|
|
229
|
+
* heatmap blended over the frame: near = warm (red/yellow), far = cool (blue).
|
|
230
|
+
* Sky pixels (+Infinity) leave the frame untouched unless renderSky is set.
|
|
231
|
+
*
|
|
232
|
+
* Uses getImageData/putImageData only, so it works with node-canvas as well
|
|
233
|
+
* as browser and react-native canvases.
|
|
234
|
+
*/
|
|
235
|
+
declare class RenderDepth implements Render {
|
|
236
|
+
target: string;
|
|
237
|
+
private context;
|
|
238
|
+
private style;
|
|
239
|
+
private readonly opacity;
|
|
240
|
+
private readonly renderSky;
|
|
241
|
+
constructor(options?: Partial<RenderDepthOptions>);
|
|
242
|
+
start(context: CanvasRenderingContext2D, style: Style): void;
|
|
243
|
+
draw(element: Prediction, xOffset: number, yOffset: number, xScale: number, yScale: number, streamTime: StreamTime, color?: string): void;
|
|
244
|
+
}
|
|
245
|
+
|
|
223
246
|
type Renderer2dOptions = {
|
|
224
247
|
context: CanvasRenderingContext2D;
|
|
225
248
|
rules?: Render[] | Render | undefined;
|
|
@@ -244,6 +267,7 @@ declare namespace Render2d {
|
|
|
244
267
|
function renderClasses(options?: Partial<RenderClassesOptions>): Render;
|
|
245
268
|
function renderMask(options?: Partial<RenderMaskOptions>): Render;
|
|
246
269
|
function renderContour(options?: Partial<RenderContourOptions>): Render;
|
|
270
|
+
function renderDepth(options?: Partial<RenderDepthOptions>): Render;
|
|
247
271
|
function renderFace(options?: Partial<RenderFaceOptions>): Render;
|
|
248
272
|
function renderKeypoints(options?: Partial<RenderKeyPointsOptions>): Render;
|
|
249
273
|
function renderHand(options?: Partial<RenderHandOptions>): Render;
|
|
@@ -252,4 +276,4 @@ declare namespace Render2d {
|
|
|
252
276
|
function renderTrail(options?: Partial<RenderTrailOptions>): Render;
|
|
253
277
|
}
|
|
254
278
|
|
|
255
|
-
export { BoxType, type ClassificationProperties, DEFAULT_TARGET, type Render, Render2d, RenderBlur, type RenderBlurOptions, RenderBox, type RenderBoxOptions, RenderClasses, type RenderClassesOptions, RenderContour, type RenderContourOptions, RenderFace, type RenderFaceOptions, RenderHand, type RenderHandOptions, RenderKeyPoints, type RenderKeyPointsOptions, RenderMask, type RenderMaskOptions, RenderPose, type RenderPoseOptions, type RenderTarget, RenderText, type RenderTextOptions, RenderTrail, type RenderTrailOptions, type Renderer, Renderer2d, type Renderer2dOptions, Render2d as default };
|
|
279
|
+
export { BoxType, type ClassificationProperties, DEFAULT_TARGET, type Render, Render2d, RenderBlur, type RenderBlurOptions, RenderBox, type RenderBoxOptions, RenderClasses, type RenderClassesOptions, RenderContour, type RenderContourOptions, RenderDepth, type RenderDepthOptions, RenderFace, type RenderFaceOptions, RenderHand, type RenderHandOptions, RenderKeyPoints, type RenderKeyPointsOptions, RenderMask, type RenderMaskOptions, RenderPose, type RenderPoseOptions, type RenderTarget, RenderText, type RenderTextOptions, RenderTrail, type RenderTrailOptions, type Renderer, Renderer2d, type Renderer2dOptions, Render2d as default };
|
|
@@ -220,6 +220,29 @@ declare class RenderClasses implements Render {
|
|
|
220
220
|
drawLabel(label: string, context: CanvasRenderingContext2D, xOffset: number, yOffset: number, style: Style, drawDisabled: boolean, xPadding: number, yPadding: number, labelWidth: number, labelHeight: number, borderRadius: number): void;
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
type RenderDepthOptions = {
|
|
224
|
+
opacity?: number;
|
|
225
|
+
renderSky?: boolean;
|
|
226
|
+
} & RenderTarget;
|
|
227
|
+
/**
|
|
228
|
+
* Renders a frame-level depth map (Prediction.depth) as a turbo-colormap
|
|
229
|
+
* heatmap blended over the frame: near = warm (red/yellow), far = cool (blue).
|
|
230
|
+
* Sky pixels (+Infinity) leave the frame untouched unless renderSky is set.
|
|
231
|
+
*
|
|
232
|
+
* Uses getImageData/putImageData only, so it works with node-canvas as well
|
|
233
|
+
* as browser and react-native canvases.
|
|
234
|
+
*/
|
|
235
|
+
declare class RenderDepth implements Render {
|
|
236
|
+
target: string;
|
|
237
|
+
private context;
|
|
238
|
+
private style;
|
|
239
|
+
private readonly opacity;
|
|
240
|
+
private readonly renderSky;
|
|
241
|
+
constructor(options?: Partial<RenderDepthOptions>);
|
|
242
|
+
start(context: CanvasRenderingContext2D, style: Style): void;
|
|
243
|
+
draw(element: Prediction, xOffset: number, yOffset: number, xScale: number, yScale: number, streamTime: StreamTime, color?: string): void;
|
|
244
|
+
}
|
|
245
|
+
|
|
223
246
|
type Renderer2dOptions = {
|
|
224
247
|
context: CanvasRenderingContext2D;
|
|
225
248
|
rules?: Render[] | Render | undefined;
|
|
@@ -244,6 +267,7 @@ declare namespace Render2d {
|
|
|
244
267
|
function renderClasses(options?: Partial<RenderClassesOptions>): Render;
|
|
245
268
|
function renderMask(options?: Partial<RenderMaskOptions>): Render;
|
|
246
269
|
function renderContour(options?: Partial<RenderContourOptions>): Render;
|
|
270
|
+
function renderDepth(options?: Partial<RenderDepthOptions>): Render;
|
|
247
271
|
function renderFace(options?: Partial<RenderFaceOptions>): Render;
|
|
248
272
|
function renderKeypoints(options?: Partial<RenderKeyPointsOptions>): Render;
|
|
249
273
|
function renderHand(options?: Partial<RenderHandOptions>): Render;
|
|
@@ -252,4 +276,4 @@ declare namespace Render2d {
|
|
|
252
276
|
function renderTrail(options?: Partial<RenderTrailOptions>): Render;
|
|
253
277
|
}
|
|
254
278
|
|
|
255
|
-
export { BoxType, type ClassificationProperties, DEFAULT_TARGET, type Render, Render2d, RenderBlur, type RenderBlurOptions, RenderBox, type RenderBoxOptions, RenderClasses, type RenderClassesOptions, RenderContour, type RenderContourOptions, RenderFace, type RenderFaceOptions, RenderHand, type RenderHandOptions, RenderKeyPoints, type RenderKeyPointsOptions, RenderMask, type RenderMaskOptions, RenderPose, type RenderPoseOptions, type RenderTarget, RenderText, type RenderTextOptions, RenderTrail, type RenderTrailOptions, type Renderer, Renderer2d, type Renderer2dOptions, Render2d as default };
|
|
279
|
+
export { BoxType, type ClassificationProperties, DEFAULT_TARGET, type Render, Render2d, RenderBlur, type RenderBlurOptions, RenderBox, type RenderBoxOptions, RenderClasses, type RenderClassesOptions, RenderContour, type RenderContourOptions, RenderDepth, type RenderDepthOptions, RenderFace, type RenderFaceOptions, RenderHand, type RenderHandOptions, RenderKeyPoints, type RenderKeyPointsOptions, RenderMask, type RenderMaskOptions, RenderPose, type RenderPoseOptions, type RenderTarget, RenderText, type RenderTextOptions, RenderTrail, type RenderTrailOptions, type Renderer, Renderer2d, type Renderer2dOptions, Render2d as default };
|
|
@@ -37,6 +37,7 @@ __export(index_exports, {
|
|
|
37
37
|
RenderBox: () => RenderBox,
|
|
38
38
|
RenderClasses: () => RenderClasses,
|
|
39
39
|
RenderContour: () => RenderContour,
|
|
40
|
+
RenderDepth: () => RenderDepth,
|
|
40
41
|
RenderFace: () => RenderFace,
|
|
41
42
|
RenderHand: () => RenderHand,
|
|
42
43
|
RenderKeyPoints: () => RenderKeyPoints,
|
|
@@ -4201,6 +4202,121 @@ var RenderClasses = class {
|
|
|
4201
4202
|
}
|
|
4202
4203
|
};
|
|
4203
4204
|
|
|
4205
|
+
// render-depth.ts
|
|
4206
|
+
var TURBO_ANCHORS = [
|
|
4207
|
+
[48, 18, 59],
|
|
4208
|
+
[62, 86, 196],
|
|
4209
|
+
[33, 145, 237],
|
|
4210
|
+
[26, 192, 181],
|
|
4211
|
+
[94, 223, 105],
|
|
4212
|
+
[181, 229, 54],
|
|
4213
|
+
[243, 192, 52],
|
|
4214
|
+
[246, 117, 26],
|
|
4215
|
+
[122, 4, 3]
|
|
4216
|
+
];
|
|
4217
|
+
var SKY_COLOR = [48, 18, 59];
|
|
4218
|
+
var isLittleEndianPlatform = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
|
|
4219
|
+
function decodeDepthValues(base64, width, height) {
|
|
4220
|
+
if (!Number.isSafeInteger(width) || width <= 0 || !Number.isSafeInteger(height) || height <= 0 || !Number.isSafeInteger(width * height * 4)) {
|
|
4221
|
+
throw new Error(`invalid depth dimensions: ${width}x${height}`);
|
|
4222
|
+
}
|
|
4223
|
+
const count = width * height;
|
|
4224
|
+
const buffer = Buffer.from(base64, "base64");
|
|
4225
|
+
if (buffer.byteLength !== count * 4) {
|
|
4226
|
+
throw new Error(`depth values hold ${buffer.byteLength} bytes, expected ${count * 4} float32 bytes`);
|
|
4227
|
+
}
|
|
4228
|
+
if (isLittleEndianPlatform) {
|
|
4229
|
+
const aligned = new Uint8Array(buffer);
|
|
4230
|
+
return new Float32Array(aligned.buffer, 0, count);
|
|
4231
|
+
}
|
|
4232
|
+
const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
4233
|
+
const values = new Float32Array(count);
|
|
4234
|
+
for (let i = 0; i < count; i++) {
|
|
4235
|
+
values[i] = view.getFloat32(i * 4, true);
|
|
4236
|
+
}
|
|
4237
|
+
return values;
|
|
4238
|
+
}
|
|
4239
|
+
function turboColor(position) {
|
|
4240
|
+
const scaled = Math.min(Math.max(position, 0), 1) * (TURBO_ANCHORS.length - 1);
|
|
4241
|
+
const lower = Math.floor(scaled);
|
|
4242
|
+
const upper = Math.min(lower + 1, TURBO_ANCHORS.length - 1);
|
|
4243
|
+
const fraction = scaled - lower;
|
|
4244
|
+
return [
|
|
4245
|
+
TURBO_ANCHORS[lower][0] * (1 - fraction) + TURBO_ANCHORS[upper][0] * fraction,
|
|
4246
|
+
TURBO_ANCHORS[lower][1] * (1 - fraction) + TURBO_ANCHORS[upper][1] * fraction,
|
|
4247
|
+
TURBO_ANCHORS[lower][2] * (1 - fraction) + TURBO_ANCHORS[upper][2] * fraction
|
|
4248
|
+
];
|
|
4249
|
+
}
|
|
4250
|
+
var RenderDepth = class {
|
|
4251
|
+
constructor(options = {}) {
|
|
4252
|
+
this.target = "$";
|
|
4253
|
+
const { target = "$", opacity = 0.5, renderSky = false } = options;
|
|
4254
|
+
this.target = target;
|
|
4255
|
+
this.opacity = Math.min(Math.max(opacity, 0), 1);
|
|
4256
|
+
this.renderSky = renderSky;
|
|
4257
|
+
}
|
|
4258
|
+
start(context, style) {
|
|
4259
|
+
this.context = context;
|
|
4260
|
+
this.style = style;
|
|
4261
|
+
}
|
|
4262
|
+
draw(element, xOffset, yOffset, xScale, yScale, streamTime, color) {
|
|
4263
|
+
const context = this.context;
|
|
4264
|
+
if (!context || !this.style) {
|
|
4265
|
+
throw new Error("render() called before start()");
|
|
4266
|
+
}
|
|
4267
|
+
if (!element.depth) {
|
|
4268
|
+
return;
|
|
4269
|
+
}
|
|
4270
|
+
const depthWidth = element.depth.width;
|
|
4271
|
+
const depthHeight = element.depth.height;
|
|
4272
|
+
const values = decodeDepthValues(element.depth.values, depthWidth, depthHeight);
|
|
4273
|
+
const destWidth = Math.round(element.source_width * xScale);
|
|
4274
|
+
const destHeight = Math.round(element.source_height * yScale);
|
|
4275
|
+
if (destWidth <= 0 || destHeight <= 0) {
|
|
4276
|
+
return;
|
|
4277
|
+
}
|
|
4278
|
+
let finiteMin = Number.POSITIVE_INFINITY;
|
|
4279
|
+
let finiteMax = Number.NEGATIVE_INFINITY;
|
|
4280
|
+
for (let i = 0; i < values.length; i++) {
|
|
4281
|
+
const value = values[i];
|
|
4282
|
+
if (Number.isFinite(value)) {
|
|
4283
|
+
if (value < finiteMin) finiteMin = value;
|
|
4284
|
+
if (value > finiteMax) finiteMax = value;
|
|
4285
|
+
}
|
|
4286
|
+
}
|
|
4287
|
+
const span = finiteMax > finiteMin ? finiteMax - finiteMin : 1;
|
|
4288
|
+
const dest = context.getImageData(xOffset, yOffset, destWidth, destHeight);
|
|
4289
|
+
const pixels = dest.data;
|
|
4290
|
+
for (let y = 0; y < destHeight; y++) {
|
|
4291
|
+
const mapY = Math.min(Math.floor(y * depthHeight / destHeight), depthHeight - 1);
|
|
4292
|
+
const mapRow = mapY * depthWidth;
|
|
4293
|
+
for (let x = 0; x < destWidth; x++) {
|
|
4294
|
+
const mapX = Math.min(Math.floor(x * depthWidth / destWidth), depthWidth - 1);
|
|
4295
|
+
const value = values[mapRow + mapX];
|
|
4296
|
+
let heat;
|
|
4297
|
+
if (Number.isFinite(value)) {
|
|
4298
|
+
const normalized = Number.isFinite(finiteMin) ? (value - finiteMin) / span : 0;
|
|
4299
|
+
heat = turboColor(1 - normalized);
|
|
4300
|
+
} else if (this.renderSky) {
|
|
4301
|
+
heat = SKY_COLOR;
|
|
4302
|
+
} else {
|
|
4303
|
+
continue;
|
|
4304
|
+
}
|
|
4305
|
+
const index = (y * destWidth + x) * 4;
|
|
4306
|
+
const destinationAlpha = pixels[index + 3] / 255 * (1 - this.opacity);
|
|
4307
|
+
const outAlpha = this.opacity + destinationAlpha;
|
|
4308
|
+
if (outAlpha > 0) {
|
|
4309
|
+
pixels[index] = Math.round((heat[0] * this.opacity + pixels[index] * destinationAlpha) / outAlpha);
|
|
4310
|
+
pixels[index + 1] = Math.round((heat[1] * this.opacity + pixels[index + 1] * destinationAlpha) / outAlpha);
|
|
4311
|
+
pixels[index + 2] = Math.round((heat[2] * this.opacity + pixels[index + 2] * destinationAlpha) / outAlpha);
|
|
4312
|
+
}
|
|
4313
|
+
pixels[index + 3] = Math.round(outAlpha * 255);
|
|
4314
|
+
}
|
|
4315
|
+
}
|
|
4316
|
+
context.putImageData(dest, xOffset, yOffset);
|
|
4317
|
+
}
|
|
4318
|
+
};
|
|
4319
|
+
|
|
4204
4320
|
// index.ts
|
|
4205
4321
|
var Render2d;
|
|
4206
4322
|
((Render2d2) => {
|
|
@@ -4228,6 +4344,10 @@ var Render2d;
|
|
|
4228
4344
|
return new RenderContour(options);
|
|
4229
4345
|
}
|
|
4230
4346
|
Render2d2.renderContour = renderContour;
|
|
4347
|
+
function renderDepth(options = {}) {
|
|
4348
|
+
return new RenderDepth(options);
|
|
4349
|
+
}
|
|
4350
|
+
Render2d2.renderDepth = renderDepth;
|
|
4231
4351
|
function renderFace(options = {}) {
|
|
4232
4352
|
return new RenderFace(options);
|
|
4233
4353
|
}
|
|
@@ -4263,6 +4383,7 @@ var index_default = Render2d;
|
|
|
4263
4383
|
RenderBox,
|
|
4264
4384
|
RenderClasses,
|
|
4265
4385
|
RenderContour,
|
|
4386
|
+
RenderDepth,
|
|
4266
4387
|
RenderFace,
|
|
4267
4388
|
RenderHand,
|
|
4268
4389
|
RenderKeyPoints,
|