无法读取 null 的属性(读取 'video')
Cannot read properties of null (reading 'video')
我正在尝试使用 React 和 face 制作情绪检测网络应用程序-api.js
我有一个开关可以打开网络摄像头,载入面部 api.js 模型并开始检测面部和情绪。我的问题是每当我 'turn off' 切换或离开 Camera.jsx 组件时,我都会在控制台中收到垃圾邮件:
这是 Camera.jsx 组件的代码:
import React, { useEffect, useState, useRef } from 'react'
import * as face from 'face-api.js';
import Switch from '@mui/material/Switch';
import './Camera.css';
import Webcam from 'react-webcam';
const Camera = () => {
const camHeight = 720;
const camWidth = 1280;
const videoRef = useRef(null);
const canvasRef = useRef(null);
const displaySize = {
width: camWidth,
height: camHeight
}
const [checked, setChecked] = useState(false);
const handleChange = (event) => {
setChecked(event.target.checked);
};
useEffect(() => {
if (checked) {
const MODEL_URL = `/models`
const initModels = async () => {
Promise.all([
face.loadTinyFaceDetectorModel(MODEL_URL),
face.loadFaceLandmarkModel(MODEL_URL),
face.loadFaceRecognitionModel(MODEL_URL),
face.loadFaceExpressionModel(MODEL_URL)
]);
}
initModels();
}
}, [checked]);
const faceAnalysis = () => {
face.matchDimensions(canvasRef.current, displaySize);
setInterval(async () => {
const detections = await face.detectAllFaces(videoRef.current.video, new face.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceExpressions();
const resizedDetections = face.resizeResults(detections, displaySize);
canvasRef.current.getContext('2d').clearRect(0, 0, camWidth, camHeight);
face.draw.drawDetections(canvasRef.current, resizedDetections);
face.draw.drawFaceLandmarks(canvasRef.current, resizedDetections);
face.draw.drawFaceExpressions(canvasRef.current, resizedDetections);
}, 50);
}
return (
<div className="analysis">
<Switch
checked={checked}
onChange={handleChange}
inputProps={{ 'aria-label': 'controlled' }}
/>
{ checked ?
<div className="camera">
<Webcam
ref={videoRef}
videoConstraints={displaySize}
onUserMedia={faceAnalysis}
/>
<canvas ref={canvasRef} />
</div>
: null}
</div>
)
}
export default Camera;
我在模型中加载情绪检测的方式会不会有问题?
我通过在 Camera.jsx 组件中创建一个函数并用 try/catch 块包围它并清除捕获中的间隔找到了解决方案,如下所示:
const drawFaceInterval = () => {
setInterval(async () => {
try {
const detections = await face.detectAllFaces(videoRef.current.video, new face.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceExpressions();
const resizedDetections = face.resizeResults(detections, displaySize);
canvasRef.current.getContext('2d').clearRect(0, 0, camWidth, camHeight);
face.draw.drawDetections(canvasRef.current, resizedDetections);
face.draw.drawFaceLandmarks(canvasRef.current, resizedDetections);
face.draw.drawFaceExpressions(canvasRef.current, resizedDetections);
} catch (error) {
clearInterval(drawFaceInterval);
}
}, 50);
}
并在我的 faceAnalysis() 函数中调用它:
const faceAnalysis = () => {
face.matchDimensions(canvasRef.current, displaySize);
drawFaceInterval();
}
我正在尝试使用 React 和 face 制作情绪检测网络应用程序-api.js
我有一个开关可以打开网络摄像头,载入面部 api.js 模型并开始检测面部和情绪。我的问题是每当我 'turn off' 切换或离开 Camera.jsx 组件时,我都会在控制台中收到垃圾邮件:
这是 Camera.jsx 组件的代码:
import React, { useEffect, useState, useRef } from 'react'
import * as face from 'face-api.js';
import Switch from '@mui/material/Switch';
import './Camera.css';
import Webcam from 'react-webcam';
const Camera = () => {
const camHeight = 720;
const camWidth = 1280;
const videoRef = useRef(null);
const canvasRef = useRef(null);
const displaySize = {
width: camWidth,
height: camHeight
}
const [checked, setChecked] = useState(false);
const handleChange = (event) => {
setChecked(event.target.checked);
};
useEffect(() => {
if (checked) {
const MODEL_URL = `/models`
const initModels = async () => {
Promise.all([
face.loadTinyFaceDetectorModel(MODEL_URL),
face.loadFaceLandmarkModel(MODEL_URL),
face.loadFaceRecognitionModel(MODEL_URL),
face.loadFaceExpressionModel(MODEL_URL)
]);
}
initModels();
}
}, [checked]);
const faceAnalysis = () => {
face.matchDimensions(canvasRef.current, displaySize);
setInterval(async () => {
const detections = await face.detectAllFaces(videoRef.current.video, new face.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceExpressions();
const resizedDetections = face.resizeResults(detections, displaySize);
canvasRef.current.getContext('2d').clearRect(0, 0, camWidth, camHeight);
face.draw.drawDetections(canvasRef.current, resizedDetections);
face.draw.drawFaceLandmarks(canvasRef.current, resizedDetections);
face.draw.drawFaceExpressions(canvasRef.current, resizedDetections);
}, 50);
}
return (
<div className="analysis">
<Switch
checked={checked}
onChange={handleChange}
inputProps={{ 'aria-label': 'controlled' }}
/>
{ checked ?
<div className="camera">
<Webcam
ref={videoRef}
videoConstraints={displaySize}
onUserMedia={faceAnalysis}
/>
<canvas ref={canvasRef} />
</div>
: null}
</div>
)
}
export default Camera;
我在模型中加载情绪检测的方式会不会有问题?
我通过在 Camera.jsx 组件中创建一个函数并用 try/catch 块包围它并清除捕获中的间隔找到了解决方案,如下所示:
const drawFaceInterval = () => {
setInterval(async () => {
try {
const detections = await face.detectAllFaces(videoRef.current.video, new face.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceExpressions();
const resizedDetections = face.resizeResults(detections, displaySize);
canvasRef.current.getContext('2d').clearRect(0, 0, camWidth, camHeight);
face.draw.drawDetections(canvasRef.current, resizedDetections);
face.draw.drawFaceLandmarks(canvasRef.current, resizedDetections);
face.draw.drawFaceExpressions(canvasRef.current, resizedDetections);
} catch (error) {
clearInterval(drawFaceInterval);
}
}, 50);
}
并在我的 faceAnalysis() 函数中调用它:
const faceAnalysis = () => {
face.matchDimensions(canvasRef.current, displaySize);
drawFaceInterval();
}