【问题标题】:Show webcam feed, capture images and save them locally in node.js?在 node.js 中显示网络摄像头提要、捕获图像并将其保存在本地?
【发布时间】:2018-10-03 16:58:52
【问题描述】:

我正在尝试构建一个面部识别模块,以便在我的项目中使用它。该模块稍后将在 electron.js 中用于构建跨平台应用程序。

基本思路是:

向用户展示了一个网页,该网页显示了他/她的网络摄像头供稿。她/他可以单击捕获按钮,将图像保存在服务器端。这将重复多次以获得训练数据来训练面部识别模型。我使用名为“node-webcam”的第三方 npm 模块实现了图像捕获部分:

const nodeWebCam = require('node-webcam');
const fs = require('fs');
const app = require('express')();
const path = require('path');

// specifying parameters for the pictures to be taken
var options = {
    width: 1280,
    height: 720, 
    quality: 100,
    delay: 1,
    saveShots: true,
    output: "jpeg",
    device: false,
    callbackReturn: "location"
};

// create instance using the above options
var webcam = nodeWebCam.create(options);

// capture function that snaps <amount> images and saves them with the given name in a folder of the same name
var captureShot = (amount, i, name) => {
    var path = `./images/${name}`;

    // create folder if and only if it does not exist
    if(!fs.existsSync(path)) {
        fs.mkdirSync(path);
    } 

    // capture the image
    webcam.capture(`./images/${name}/${name}${i}.${options.output}`, (err, data) => {
        if(!err) {
            console.log('Image created')
        }
        console.log(err);
        i++;
        if(i <= amount) {
            captureShot(amount, i, name);
        }
    });  
};

// call the capture function
captureShot(30, 1, 'robin');

app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'index.html'));
});

app.listen(3000, () => {
    console.log("Listening at port 3000....");
});

但是,在这部分之后我迷路了。我不知道如何让实时提要显示在用户看到的网页上。另外,我后来意识到这是一个服务器端代码,没有办法从客户端调用 captureShot() 函数。任何帮助将不胜感激。

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    将捕获镜头变成承诺,然后在路线中渲染。我们将设置一个运行函数的路由,然后使用 HTML 字符串返回图像的路径。我不知道如何从您的函数返回数据以制作图像。但是假设它返回了确切的路径,你就可以解析回调的路径。

    您还需要创建一个由 express 提供的静态目录。所以你可以使用http://localhost:3000/myimage.jpg

    const nodeWebCam = require('node-webcam');
    const fs = require('fs');
    const app = require('express')();
    const path = require('path');
    
    app.use(express.static('images')) // images folder to be served
    // Now we can just say localhost:3000/image.jpg
    
    // specifying parameters for the pictures to be taken
    var options = {
        width: 1280,
        height: 720, 
        quality: 100,
        delay: 1,
        saveShots: true,
        output: "jpeg",
        device: false,
        callbackReturn: "location"
    };
    
    // create instance using the above options
    var webcam = nodeWebCam.create(options);
    
    // capture function that snaps <amount> images and saves them with the given name in a folder of the same name
    var captureShot = (amount, i, name) => {
     // Make sure this returns a real url to an image.
     return new Promise(resolve => {
        var path = `./images/${name}`;
    
        // create folder if and only if it does not exist
        if(!fs.existsSync(path)) {
            fs.mkdirSync(path);
        } 
    
        // capture the image
        webcam.capture(`./images/${name}/${name}${i}.${options.output}`, (err, data) => {
            if(!err) {
                console.log('Image created')
            }
            console.log(err);
            i++;
            if(i <= amount) {
                captureShot(amount, i, name);
            }
            resolve('/path/to/image.jpg')
        }); 
     })
    
    };
    
    // call the capture function
    
    
    app.get('/', (req, res) => {
        captureShot(30, 1, 'robin');
          .then((response) => { 
            // Whatever we resolve in captureShot, that's what response will contain
             res.send('<img src="${response}"/>')
          })
    });
    
    app.listen(3000, () => {
        console.log("Listening at port 3000....");
    });
    

    如果您尝试设计具有特定动态内容的页面。使用带有 express 的模板引擎,例如 EJS。 http://ejs.co 然后您可以使用动态对象渲染页面。并在拍照后动态给用户设置一个&lt;img src=&lt;%= image %&gt;/&gt;

    我放了一个 promise 的例子,然后使用 express 的静态目录。你可以明白我在说什么。

    function create() {
      return new Promise(resolve => {
         if (true) {
            resolve('https://example.com/image.jpg')
         } else {
            reject('Error')
         }
      })
    }
    
    create()
      .then((response) => {
         console.log(`<img src="${response}"/>`)
      })
      .catch((error) => {
         // Error
         console.log(error)
      })

    【讨论】:

      【解决方案2】:

      我正在研究一种基于 puppeteer(无头谷歌浏览器)的解决方案,该解决方案具有超级便携性,并且能够以可接受的速度快速传输视频(40fps 800x600 帧)。非常易于安装和使用,我已经在使用它在基于 gtk、cairo、opengl 和 qt 的桌面应用程序上捕获视频、音频和桌面,没有任何问题。

      https://www.npmjs.com/package/camera-capture

      我对 opencv 很熟悉,但是基于它的库真的很难被新用户安装。我的项目不需要任何本机依赖项或客户端-服务器通信,尽管它对于嵌入小型设备可能是非轻量级的(puppeteer 大小约为 80mb)。欢迎反馈!谢谢

      【讨论】:

        猜你喜欢
        • 2013-03-17
        • 1970-01-01
        • 2013-06-03
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-09
        相关资源
        最近更新 更多