gpt4 book ai didi

node.js - BodyPix - 在 node.js 中运行 toMask() 和 toColoredPartMask() 会引发错误 : ImageData is not defined

转载 作者:行者123 更新时间:2023-12-05 06:01:22 28 4
gpt4 key购买 nike

我正在尝试在 TensorFlowJS bodypix 模型中获取分段的人物部位彩色面具。下面的代码在抛出错误“ImageData 未定义”的 toColoredPartMask 或 toMask 之前工作正常。

const tfjsnode = require('@tensorflow/tfjs-node')
const bodyPix = require('@tensorflow-models/body-pix');
const fs = require('fs');

setTimeout(async () => {
maskImageWithBodyPix().then(response => {
console.log(response)
}).catch(e => {
console.log("Error => " + e)
})
}, 1000)

async function maskImageWithBodyPix(image = readImage("./person.jpeg")) {

console.log("loadModel ...");
if (image == null)
return Promise.resolve("Image Not Found...")
const resNet = {
architecture: 'ResNet50',
outputStride: 16,
quantBytes: 4
};
let bodyModel = await bodyPix.load(resNet)

console.log("segmentPersonParts ...");
let segmentedPersonParts = await bodyModel.segmentPersonParts(image, {
flipHorizontal: false,
internalResolution: 'full',
segmentationThreshold: 0.5,
})
console.log(`ImageHeight: ${segmentedPersonParts.height} | ImageWidth: ${segmentedPersonParts.width}`)
console.log("toMaskImageData ...")
const maskedImageData = bodyPix.toColoredPartMask(segmentedPersonParts, false);

console.log(`maskedImageData = ${maskedImageData}`)

return Promise.resolve(true)
}

const readImage = path => {
console.log(`readImage ...`)
if (!fs.existsSync(path))
return null
const imageBuffer = fs.readFileSync(path);
const tfimage = tfjsnode.node.decodeImage(imageBuffer);
return tfimage;
}

最佳答案

所以这是一个巨大的 hack,但我成功了。

问题出在node_modules\@tensorflow-models\body-pix\dist\output_rendering_util.js

如果我们看一下里面的这个函数:

function toColoredPartMask(partSegmentation, partColors) {
if (partColors === void 0) { partColors = RAINBOW_PART_COLORS; }
if (Array.isArray(partSegmentation) && partSegmentation.length === 0) {
return null;
}
var multiPersonPartSegmentation;
if (!Array.isArray(partSegmentation)) {
multiPersonPartSegmentation = [partSegmentation];
}
else {
multiPersonPartSegmentation = partSegmentation;
}
var _a = multiPersonPartSegmentation[0], width = _a.width, height = _a.height;
var bytes = new Uint8ClampedArray(width * height * 4);
for (var i = 0; i < height * width; ++i) {
// invert mask. Invert the segmentation mask.
var j = i * 4;
bytes[j + 0] = 255;
bytes[j + 1] = 255;
bytes[j + 2] = 255;
bytes[j + 3] = 255;
for (var k = 0; k < multiPersonPartSegmentation.length; k++) {
var partId = multiPersonPartSegmentation[k].data[i];
if (partId !== -1) {
var color = partColors[partId];
if (!color) {
throw new Error("No color could be found for part id " + partId);
}
bytes[j + 0] = color[0];
bytes[j + 1] = color[1];
bytes[j + 2] = color[2];
bytes[j + 3] = 255;
}
}
}
return new ImageData(bytes, width, height);
}

它似乎返回了一个新的 ImageData 对象。但是,如果我们查看 ImageData 实际上是什么,我们会得到:

imagedata

如果我们深入挖掘,我们会找到一些 node.js 内部 typescript 文件并看到:

declare var ImageData: {
prototype: ImageData;
new(sw: number, sh: number, settings?: ImageDataSettings): ImageData;
new(data: Uint8ClampedArray, sw: number, sh?: number, settings?: ImageDataSettings): ImageData;
};

我认为这对我们不起作用,所以我们需要以某种方式覆盖该引用。

我所做的是install this package here并将 const ImageData = require("@canvas/image-data"); 行添加到 node_modules\@tensorflow-models\body-pix\dist\output_rendering_util.js 的最顶部 像这样的文件:

"use strict";
/**
* @license
* Copyright 2019 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
const ImageData = require("@canvas/image-data");
Object.defineProperty(exports, "__esModule", { value: true });
...

现在,当我们再次查看 ImageData 时,我们得到:

new imagedata

只需这样做并从 toColoredPartMask 调用中删除 false 参数,它就这样调用:

const maskedImageData = bodyPix.toColoredPartMask(segmentedPersonParts);

我们得到这个结果:

maskedImageData

如果我们要 JSON.stringify(maskedImageData),我们会得到十亿行一些数字,所以我不打算在这里粘贴。无论如何,我认为它现在有效。

我认为问题出在 ImageData 的 node.js 实现上。我们正在使用它的某种奇怪的浏览器实现。我安装的包实现了 ImageData 的浏览器外部版本,我们强制 bodypix 使用它来代替 require。

这是我的输入图像:

input

这是输出:

output

请注意,您基本上不应该在 node_modules 中编辑任何内容,但如果这只是一个有趣的项目,我不明白为什么不尝试一下

P.S 我认为 toColoredPartMask 中检查 partColors 的第一行有点古怪,所以我将其替换为 if(arguments.length === 1 || !partColors) { partColors = RAINBOW_PART_COLORS; 在我的代码中。

关于node.js - BodyPix - 在 node.js 中运行 toMask() 和 toColoredPartMask() 会引发错误 : ImageData is not defined,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67242455/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com