opencv.js调用摄像头CPU,内存飙升,造成浏览器卡顿严重
在定义video标签宽度和高度越高的时候,opencv.js中的map.read(src)的时候浏览器CPU直接飙升。
```html
let gray2;
let denoised2;
let edges2;
let fst2;
let hierarchy2;
let approx2;
let dst1;
let dst2;
let kernel2;
let fsk2;
let sss;
let frameCount = 0;
let canvasElement1 = document.getElementById('videoCanvas');
const FPS = 30;
let begin;
let delay;
let videosrc;
let videocap;
function init() {
sss = 1;
var videoElement = document.getElementById('video');
videocap = new cv.VideoCapture(videoElement);
videosrc = new cv.Mat(videoElement.height, videoElement.width, cv.CV_8UC4);
gray2 = new cv.Mat();
denoised2 = new cv.Mat();
edges2 = new cv.Mat();
fst2 = new cv.Mat();
hierarchy2 = new cv.Mat();
approx2 = new cv.Mat();
dst1 = new cv.Mat();
dst2 = new cv.Mat();
kernel2 = cv.getStructuringElement(cv.MORPH_RECT, new cv.Size(7, 7));
fsk2 = cv.getStructuringElement(cv.MORPH_RECT, new cv.Size(5, 5));
}
function detectAndDraw() {
if (sss !== 1) {
init();
}
try {
// 确保视频正在播放
if (video.paused || video.ended) {
videosrc.delete();
videosrc = null;
gray2.delete();
denoised2.delete();
edges2.delete();
fst2.delete();
hierarchy2.delete();
approx2.delete();
dst1.delete();
dst2.delete();
kernel2.delete();
fsk2.delete();
return;
}
videocap.read(videosrc);//造成cpu,内存高占用核心问题
// 图像处理:转换为灰度图
cv.cvtColor(videosrc, gray2, cv.COLOR_BGR2GRAY); // 重用 gray2 对象
// 降噪处理
cv.bilateralFilter(gray2, denoised2, 9, 75, 75); // 重用 denoised2 对象
// 高斯滤波
cv.GaussianBlur(denoised2, denoised2, new cv.Size(5, 5), 0, 0); // 使用降噪后的图像
// 提取边缘
cv.Canny(denoised2, edges2, 75, 150); // 重用 edges2 对象
// 膨胀
cv.dilate(edges2, edges2, kernel2); // 重用 kernel2 和 edges2 对象
// 进行腐蚀操作
cv.erode(edges2, fst2, fsk2); // 重用 fst2 和 fsk2 对象
// 提取外轮廓
let contours = new cv.MatVector();
cv.findContours(edges2, contours, hierarchy2, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE);
let index = 0, maxArea = 0, aindex = 0;
const area = videosrc.cols * videosrc.rows;
for (let i = 0; i < contours.size(); ++i) {
let tempArea = Math.abs(cv.contourArea(contours.get(i)));
if (tempArea > maxArea) {
index = i;
maxArea = tempArea;
}
if (tempArea > area * 0.03) {
//console.log("底图面积:" + area + ";文件面积:" + tempArea);
aindex++;
}
}
if (maxArea > 0 && aindex === 1) {
const foundContour = contours.get(index);
const arcL = cv.arcLength(foundContour, true);
cv.approxPolyDP(foundContour, approx2, 0.02 * arcL, true); // 重用 approx2 对象
if (approx2.total() === 4) {
let points = [];
const data32S = approx2.data32S;
for (let i = 0, len = data32S.length / 2; i < len; i++) {
points[i] = {x: data32S[i * 2], y: data32S[i * 2 + 1]};
}
let srcPoints = getSortedVertex(points).flatMap(p => [p.x, p.y]);
// 在源图像上绘制绿色边框
for (let i = 0; i < 4; i++) {
const startX = srcPoints[i * 2];
const startY = srcPoints[i * 2 + 1];
const endX = srcPoints[((i + 1) % 4) * 2];
const endY = srcPoints[((i + 1) % 4) * 2 + 1];
// 绘制线段,颜色为绿色,线宽为2
cv.line(videosrc, new cv.Point(startX, startY), new cv.Point(endX, endY), new cv.Scalar(0, 255, 0, 255), 7);
}
}
}
// 释放本次使用的 Mat 对象
contours.delete();
contours = null;
} catch (e) {
console.error("发生错误:", e);
} finally {
cv.imshow(canvasElement1, videosrc);
setTimeout(detectAndDraw, 1000 / FPS);
}
}
出问题的代码方法是detectAndDraw方法,尝试一行一行的注释代码发现, videocap.read(videosrc);这一行代码和
<video id="video" width="1500" height="1125" style="display: none"></video>
<canvas id="videoCanvas" width="1500" height="1125"></canvas>
这个宽度高度相关,宽度高度越大,浏览器内存和cpu越高,请问可以如何优化,或者哪里写的有问题吗?
目前这样写单个页面内存达到700M,,CP90%左右