编译opencv.js

opencv 支持编译多个平台,其中还支持JavaScript,不过编译需要emscripten

编译环境:centos7,Python2.7

1.下载OpenCV源码

官网:https://opencv.org/releases/

例如下载4.8.0版本:

https://github.com/opencv/opencv/archive/4.8.0.zip

2.利用镜像 trzeci/emscripten 构建

#解压OpenCV

unzip opencv-4.8.0.zip

#进入opencv-4.8.0

cd opencv-4.8.0

#拉最新的trzeci/emscripten

docker pull trzeci/emscripten

#开始编译

docker run --rm --workdir /code -v "$PWD":/code "trzeci/emscripten" python ./platforms/js/build_js.py buildjs

最后编译结果都放在buildjs,其中opencv.js 在 buildjs/bin 下面,拷贝出来就可以用了

当然,也可以直接线上已经编译好的:

https://docs.opencv.org/4.8.0/opencv.js

附上 nodejs 示例

js 复制代码
const { Canvas, createCanvas, Image, ImageData, loadImage } = require('canvas');
const { JSDOM } = require('jsdom');
const { writeFileSync, existsSync, mkdirSync } = require('fs');
(async () => {
    await loadOpenCV();
    await detect('../out/imgs/lena.jpg')
})();



const detect = async(imgPath) => {
    console.time(imgPath)
    const image = await loadImage(imgPath);
    const src = cv.imread(image);
    let gray = new cv.Mat();
    cv.cvtColor(src, gray, cv.COLOR_RGBA2GRAY, 0);
    let faces = new cv.RectVector();
    let eyes = new cv.RectVector();
    let faceCascade = new cv.CascadeClassifier();
    let eyeCascade = new cv.CascadeClassifier();
    // Load pre-trained classifier files. Notice how we reference local files using relative paths just
    // like we normally would do
    faceCascade.load('./models/haarcascade_frontalface_alt2.xml');
    eyeCascade.load('./models/haarcascade_eye.xml');
    let mSize = new cv.Size(100, 100);
    faceCascade.detectMultiScale(gray, faces, 1.11, 6, 0, mSize);
    console.timeEnd(imgPath)
    console.log('face size: ',faces.size())
    for(let i=0;i<faces.size();i++) {
        console.log(faces.get(i))
    }
    for (let i = 0; i < faces.size(); ++i) {
        let roiGray = gray.roi(faces.get(i));
        let roiSrc = src.roi(faces.get(i));
        let point1 = new cv.Point(faces.get(i).x, faces.get(i).y);
        let point2 = new cv.Point(faces.get(i).x + faces.get(i).width, faces.get(i).y + faces.get(i).height);
        cv.rectangle(src, point1, point2, [255, 0, 0, 255]);
        eyeCascade.detectMultiScale(roiGray, eyes);
        console.log(eyes.size(),'eyes')
        for (let j = 0; j < eyes.size(); ++j) {
            let point1 = new cv.Point(eyes.get(j).x, eyes.get(j).y);
            let point2 = new cv.Point(eyes.get(j).x + eyes.get(j).width, eyes.get(j).y + eyes.get(j).height);
            cv.rectangle(roiSrc, point1, point2, [0, 0, 255, 255]);
        }
        roiGray.delete();
        roiSrc.delete();
    }
     const canvas = createCanvas(image.width, image.height);
     cv.imshow(canvas, src);
     writeFileSync(imgPath+'-output.jpg', canvas.toBuffer('image/jpeg'));
    src.delete(); gray.delete(); faceCascade.delete(); 
    eyeCascade.delete(); 
    faces.delete(); 
    eyes.delete()
}

/**
 * Loads opencv.js.
 *
 * Installs HTML Canvas emulation to support `cv.imread()` and `cv.imshow`
 *
 * Mounts given local folder `localRootDir` in emscripten filesystem folder `rootDir`. By default it will mount the local current directory in emscripten `/work` directory. This means that `/work/foo.txt` will be resolved to the local file `./foo.txt`
 * @param {string} rootDir The directory in emscripten filesystem in which the local filesystem will be mount.
 * @param {string} localRootDir The local directory to mount in emscripten filesystem.
 * @returns {Promise} resolved when the library is ready to use.
 */
function loadOpenCV (rootDir = './work', localRootDir = process.cwd()) {
    if (global.Module && global.Module.onRuntimeInitialized && global.cv && global.cv.imread) {
        return Promise.resolve()
    }
    return new Promise(resolve => {
        installDOM()
        global.Module = {
            onRuntimeInitialized () {
                // We change emscripten current work directory to 'rootDir' so relative paths are resolved
                // relative to the current local folder, as expected
                cv.FS.chdir(rootDir)
                resolve()
            },
            preRun () {
                // preRun() is another callback like onRuntimeInitialized() but is called just before the
                // library code runs. Here we mount a local folder in emscripten filesystem and we want to
                // do this before the library is executed so the filesystem is accessible from the start
                const FS = global.Module.FS
                // create rootDir if it doesn't exists
                if (!FS.analyzePath(rootDir).exists) {
                    FS.mkdir(rootDir);
                }
                // create localRootFolder if it doesn't exists
                if (!existsSync(localRootDir)) {
                    mkdirSync(localRootDir, { recursive: true });
                }
                // FS.mount() is similar to Linux/POSIX mount operation. It basically mounts an external
                // filesystem with given format, in given current filesystem directory.
                FS.mount(FS.filesystems.NODEFS, { root: localRootDir }, rootDir);
            }
        };
        global.cv = require('./opencv.js')
    });
}
function installDOM () {
    const dom = new JSDOM();
    global.document = dom.window.document;
    global.Image = Image;
    global.HTMLCanvasElement = Canvas;
    global.ImageData = ImageData;
    global.HTMLImageElement = Image;
}
相关推荐
codingandsleeping10 小时前
Express入门
javascript·后端·node.js
Icoolkj10 小时前
在 Windows 系统上升级 Node.js
windows·node.js
Blossom.11811 小时前
量子网络:构建未来通信的超高速“高速公路”
网络·opencv·算法·安全·机器学习·密码学·量子计算
jndingxin13 小时前
OpenCV 图形API(69)图像与通道拼接函数------将一个 GMat 类型的对象转换为另一个具有不同深度GMat对象函数convertTo()
人工智能·opencv·计算机视觉
前端付豪15 小时前
3、Node.js异步编程彻底吃透
前端·后端·node.js
AI视觉网奇15 小时前
python 求内轮廓
python·opencv·计算机视觉
layman052816 小时前
node.js 实战——mongoDB
数据库·mongodb·node.js
一袋米扛几楼9819 小时前
【前端】从零开始的搭建顺序指南(技术栈:Node.js + Express + MongoDB + React)book-management
前端·node.js·express
2501_9153738819 小时前
Node.js 包管理工具介绍
node.js
诸神缄默不语20 小时前
已有 npm 项目,如何下载依赖、编译并运行项目
前端·npm·node.js