初识opencvjs

OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库。OpenCV是由英特尔公司发起并参与开发,以BSD许可证授权发行,可以在商业和研究领域中免费使用。OpenCV可用于开发实时的图像处理、计算机视觉以及模式识别程序。该程序库也可以使用英特尔公司的IPP进行加速处理。
OpenCV.js——连接OpenCV与JS开发者
随着HTML5的兴起,在web端使用图像处理相关技术显得尤为重要,OpenCV.js为Javascript开发者与OpenCV之间搭建了桥梁。起初是由Intel公司发起的一项研究,后在2017年并入到OpenCV项目中。
Emscripten,一款LLVM-to-JavaScript的编译器,将C++的底层函数编译成可以直接在浏览器端运行的asm.js或者WebAssembly。而OpenCV.js是通过该Emscripten将OpenCV的函数编译进asm.js或WebAssembly中,并提供JS APIs给web应用使用。
OpenCV.js的目标:
1. 实现OpenCV在web端的开发与使用
2. 帮助网络社区,开发人员和计算机视觉研究人员交互访问各种基于Web的OpenCV示例,帮助他们理解特定的视觉算法。
基本概念与操作
矩阵
OpenCV.js 引入了新的变量类型 —— Mat类型,即矩阵类型,使用 let mat = new cv.Mat(); 来创建新的矩阵类型,OpenCV.js 读取的图像均使用该类型存储。
图像的读取与写入
OpenCV.js 可以将 或者 的内容读取为矩阵类型用以变换,同时也可以将处理好的图像作为 或者 的内容,具体方法如下:
// 读取
let mat = cv.imread("inputCanvasId");
// 其中 inputCanvasId 为目标 DOM 元素的 id 属性

// 写入
cv.imshow(mat, "outputCanvasId");
// mat 为处理后图像矩阵变量
官方已经提供比较完整的说明文档,这里不详细介绍具体的 API 了,我们简单说一下用法。注意:所有的代码应该写在初始化函数onRuntimeInitialized中。cv 提供了imread(imageid | HTMLImageElement | HTMLCanvasElement) 的函数签名,这可以从指定的源读取图片内容,并返回一个cv.Mat类型的对象,这是一个基本的存储二维空间的数据结构——矩阵,这里用来存储图片的像素结构,后面很多操作都是基于Mat类型来操作的。输出图片也非常方便,直接调用cv.imshow(canvasid | HTMLCanvasElement, cv.Mat对象) 就可以把图像绘制在屏幕上。需要记住的是 WebAssembly 不会帮助你回收内存,所以记得 cv.Mat 对象用完后及时调用delete()方法释放内存。
图像数据类型
Mat 是 OpenCV 基础的图像数据结构,其数据类型对照表如下:

| Data Properties

| C++Type | JavaScript Typed Array | Mat Type | | --- | --- | --- | --- | | data | uchar | Uint8Array | CV_8U | | data8S | char | Int8Array | CV_8S | | data16U | ushort | Uint16Array | CV_16U | | data16S | short | Int16Array | CV_16S | | data32S | int | Int32Array | CV_32S | | data32F | float | Float32Array | CV_32F | | data64F | double | Float64Array | CV_64F |

灰度实现


    
        OpenCV.js
        
            .wrap-image {
                display: flex;
                flex-direction: row;
                margin-top: 10px;
            }
            .wrap-image img,
            .wrap-image canvas {
                width: 300px;
                margin-right: 10px;
            }
        
    

    
        Loading the Opencv ...
        
        
            
            
        
                     //图片灰度处理效果:             let imgElement = document.getElementById('imageUpload-gray');             let inputElement = document.getElementById('fileInput-gray');             inputElement.onchange = function() {               imgElement.src = URL.createObjectURL(event.target.files[0]);             }             imgElement.onload =function() {                 let src = cv.imread('imageUpload-gray');                 let dst = new cv.Mat();                 cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY, 0);                 cv.imshow('canvasOutput-gray', dst);                 src.delete(); dst.delete();             };             function onOpenCvReady() {                 document.getElementById('status').remove();             }                        初识opencvjs_第1张图片 image.png
图像阈值处理
//图片灰度处理效果:
let imgElement = document.getElementById('imageUpload');
let inputElement = document.getElementById('fileInput');

inputElement.onchange = function() {
  imgElement.src = URL.createObjectURL(event.target.files[0]);
}

imgElement.onload =function() {
    let src = cv.imread('imageUpload');
    let dst = new cv.Mat();
    // cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY, 0);
    cv.threshold(src, dst, 177, 200, cv.THRESH_BINARY);
    cv.imshow('canvasOutput', dst);
    src.delete(); dst.delete();
};
function onOpenCvReady() {
    document.getElementById('status').remove();
}
初识opencvjs_第2张图片 image.png
自适应阈值
let imgElement = document.getElementById('imageUpload');
let inputElement = document.getElementById('fileInput');

inputElement.onchange = function() {
  imgElement.src = URL.createObjectURL(event.target.files[0]);
}

imgElement.onload =function() {
    let src = cv.imread('imageUpload');
    let dst = new cv.Mat();
    cv.cvtColor(src, src, cv.COLOR_RGBA2GRAY, 0);
    // You can try more different parameters
    cv.adaptiveThreshold(src, dst, 200, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 3, 2);

    cv.imshow('canvasOutput', dst);
    src.delete(); dst.delete();
};
function onOpenCvReady() {
    document.getElementById('status').remove();
}
初识opencvjs_第3张图片 image.png
滤镜处理
let imgElement = document.getElementById('imageUpload');
let inputElement = document.getElementById('fileInput');

inputElement.onchange = function() {
  imgElement.src = URL.createObjectURL(event.target.files[0]);
}

imgElement.onload =function() {
  let src = cv.imread('imageUpload');
  let dst = new cv.Mat();
  let M = cv.Mat.eye(3, 3, cv.CV_32FC1);
  let anchor = new cv.Point(-1, -1);
  // You can try more different parameters
  cv.filter2D(src, dst, cv.CV_8U, M, anchor, 0, cv.BORDER_DEFAULT);

  cv.imshow('canvasOutput', dst);
  src.delete(); dst.delete();
};
function onOpenCvReady() {
  document.getElementById('status').remove();
}
初识opencvjs_第4张图片 image.png
图像模糊
let imgElement = document.getElementById('imageUpload');
let inputElement = document.getElementById('fileInput');

inputElement.onchange = function() {
  imgElement.src = URL.createObjectURL(event.target.files[0]);
}

imgElement.onload =function() {
    let src = cv.imread('imageUpload');
    let dst = new cv.Mat();
    let ksize = new cv.Size(3, 3);
// You can try more different parameters
cv.GaussianBlur(src, dst, ksize, 0, 0, cv.BORDER_DEFAULT);
    cv.imshow('canvasOutput', dst);
    src.delete(); dst.delete();
};
function onOpenCvReady() {
    document.getElementById('status').remove();
}
初识opencvjs_第5张图片 image.png
图像直方图
let imgElement = document.getElementById('imageUpload');
let inputElement = document.getElementById('fileInput');

inputElement.onchange = function() {
  imgElement.src = URL.createObjectURL(event.target.files[0]);
}

imgElement.onload =function() {
    let src = cv.imread('imageUpload');
        // let dst = new cv.Mat();
        // let src = cv.imread('canvasInput');
    cv.cvtColor(src, src, cv.COLOR_RGBA2GRAY, 0);
    let srcVec = new cv.MatVector();
    srcVec.push_back(src);
    let accumulate = false;
    let channels = [0];
    let histSize = [256];
    let ranges = [0, 255];
    let hist = new cv.Mat();
    let mask = new cv.Mat();
    let color = new cv.Scalar(255, 255, 255);
    let scale = 2;
    // You can try more different parameters
    cv.calcHist(srcVec, channels, mask, hist, histSize, ranges, accumulate);
    let result = cv.minMaxLoc(hist, mask);
    let max = result.maxVal;
    let dst = new cv.Mat.zeros(src.rows, histSize[0] * scale,
                            cv.CV_8UC3);
    // draw histogram
    for (let i = 0; i < histSize[0]; i++) {
        let binVal = hist.data32F[i] * src.rows / max;
        let point1 = new cv.Point(i * scale, src.rows - 1);
        let point2 = new cv.Point((i + 1) * scale - 1, src.rows - binVal);
        cv.rectangle(dst, point1, point2, color, cv.FILLED);
    }
    cv.imshow('canvasOutput', dst);
    src.delete(); dst.delete(); srcVec.delete(); mask.delete(); hist.delete();
}
function onOpenCvReady() {
    document.getElementById('status').remove();
}
初识opencvjs_第6张图片 image.png

参考文献

  • OpenCV官网

  • OpenCV.js Tutorials

  • OpenCV.js 快速入门指南

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

初识opencvjs_第7张图片

你可能感兴趣的:(初识opencvjs)