这是indexloc提供的服务,不要输入任何密码
Skip to content

Error in toNetInput function - Expected media to be of type HTMLCanvasElement, HTMLImageElement, HTMLVideoElement, or tf.Tensor3D #960

@SamLorenzoSanc

Description

@SamLorenzoSanc

I'm encountering an error when attempting to use face-api.js in a Node.js environment with a node-canvas generated canvas. The error occurs when trying to pass a canvas to the toNetInput function. The error message is:

Error: toNetInput - expected media to be of type HTMLImageElement | HTMLVideoElement | HTMLCanvasElement | tf.Tensor3D, or to be an element id at /path/to/node_modules/face-api.js/build/commonjs/dom/toNetInput.js:38:35 ...

I'm using node-canvas to load an image, resize it, and then create a canvas using createCanvas from the node-canvas package.
The canvas (localCanvas) is created and drawn onto, but when I try to pass it to face-api.js via the toNetInput function, it throws the above error.

`export const loginFacial = async (req, res) => {
try {
const { username } = req.body;

if (!req.file) {
  return res.status(400).json({ message: 'No file uploaded' });
}

const user = await User.findOne({ username });
if (!user) {
  return res.status(404).json({ message: 'User not found' });
}

if (!user.faceId || user.faceId.length === 0) {
  return res.status(400).json({ message: 'No face ID stored for user' });
}

await loadFaceApiModels();

const img = await loadImage(req.file.path);

const MAX_WIDTH = 640;
const MAX_HEIGHT = 480;
const scale = Math.min(MAX_WIDTH / img.width, MAX_HEIGHT / img.height);
const newWidth = img.width * scale;
const newHeight = img.height * scale;

const localCanvas = createCanvas(newWidth, newHeight);
const ctx = localCanvas.getContext('2d');
ctx.drawImage(img, 0, 0, newWidth, newHeight);

const input = await faceapi.toNetInput(localCanvas);
console.log('Input para face-api.js:', input); // Check the input being passed

const detections = await faceapi.detectSingleFace(input, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceDescriptor();
if (!detections) {
  return res.status(401).json({ message: 'No face detected' });
}

const storedFaceDescriptor = new Float32Array(user.faceId);
const faceMatcher = new faceapi.FaceMatcher([storedFaceDescriptor]);
const bestMatch = faceMatcher.findBestMatch(detections.descriptor);

if (bestMatch.distance < 0.6) {
  const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: '1h' });
  return res.json({ token });
} else {
  return res.status(401).json({ message: 'Face authentication failed' });
}

} catch (error) {
console.error('Error in loginFacial:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
};
`

I am passing the localCanvas (created by node-canvas) directly to face-api.js via faceapi.toNetInput(localCanvas). Even though localCanvas is a valid canvas object from node-canvas, the error suggests that face-api.js does not accept it as valid input. The toNetInput function seems to expect a standard HTMLCanvasElement, HTMLImageElement, or HTMLVideoElement from the browser context, but this is not a browser environment.

face-api.js should accept a node-canvas canvas object when running in a Node.js environment, as it can handle it properly for face detection.

face-api.js version: 0.22.2
node-canvas version: 3.1.0
Node.js version: 18.20.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions