Opencv.js使得前端工程师能够在html文件中的javascript区域编写图像处理的程序了。js作为一种使用体验与python近似的语言,写opencv代码本来就比较合适。
在一切之前,得懂JavaScript和opencv,学opencv建议使用python语言,好上手(C++天下第一的那谁在哪儿呢)。接下来以分解的方式分析一下一个包含opencv.js库的基础项目是怎么构成的。
opencv.js是个库,不过官方本身没有提供这个库文件(只给了一点实例程序块)。opencv.js库的本质是C++版本的opencv库,编译成js文件的。整个过程比较复杂,建议直接下载别人编译好的js文件。
拥有js库就舒服了,毕竟js文件外联到html文件是前端的基本操作,将html文件和opencv.js放在一个文件夹内即可。
html文件中外联此js文件的代码如下句:
<script async src="opencv.js" type="text/javascript"></script>
async是一个表示异步加载的表示属性,这样IO操作的时候就不会造成程序阻塞。加载完毕后就可以使用opencv.js库文件里面的方法了。
如果想要直观看出何时opencv.js库加载完毕的话,可以在代码中增加属性onload,指向一个回调函数,和node.js里的异步机制相同。
<script async src="opencv.js" onload="opencvLoad()" type="text/javascript"></script>
图像处理的过程一般是怎样的呢?从程序员的角度讲无非就是:1.输入图像 2.调用XX方法进行处理 3.输出图像。在js中也无非如此。
首先是输入图像。opencv.js的图像文件读取不是直接靠js内的imread函数,而是先由html的读文件操作读取文件,然后再由imread导入到矩阵变量中:
let mat=cv.imread(imgSrcElement);
步骤2这个还是没有变化,通过调用库中的函数进行图像处理。
步骤3也比较特殊。在其他版本的opencv中输出一个矩阵变量(经处理过后的图像),放在窗口里输出即可。但是html里不能随便做出新窗口的,html使用canvas组件来实现图像输出。canvas组件又被称为html画布,专门用于在网页中绘制新的图像:
cv.imshow('canvasOutput',mat);
如以上代码可见,opencv.js是将新的矩阵变量通过canvas组件显示的。
首先在页面中加入img组件与文件上传组件:
"utf-8">
OpenCV.js
Program of OpenCV.js
"status">OpenCV.js is loading...
"inputoutput">
"imageSrc" alt="No Image" />
"caption">imageSrc "file" id="fileInput" name="file" />
Hello OpenCV.js
Program of OpenCV.js
"status"
>OpenCV.js is loading...
"inputoutput">
"imageSrc" alt="No Image" />
"caption">imageSrc "file" id="fileInput" name="file" />
"inputoutput">
"caption">canvasOutput
JavaScript代码如下:
<script type="text/javascript">
var imgSrcElement=document.getElementById('imageSrc');
var imageInput=document.getElementById('fileInput');
imageInput.addEventListener('change',(e)=>{
imgSrcElement.src=URL.createObjectURL(e.target.files[0]);
})
// 因为是异步操作,所以需要onload等图像加载完毕后执行,也是回调
imgSrcElement.onload=function(){
// 读取获取矩阵(步骤1)
let mat=cv.imread(imgSrcElement);
// 输出获取矩阵(步骤3)
cv.imshow('canvasOutput',mat);
// 调用delete释放堆的内存
mat.delete();
}
var opencvLoad=function(){
document.getElementById('status').innerHTML='opencv is ready';//回调函数,用来显示opencv.js加载完成
}
</script>
<!-- 异步加载,不对程序进行阻塞 -->
<script async src="opencv.js" onload="opencvLoad()" type="text/javascript"></script>
从红框处可以看到opencv.js已经加载完毕了,可以开始操作了。点击选择文件后,从电脑上找一张图片。
结果符合预期。在canvas画布上输出了和源文件一样的图像。
整体代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello OpenCV.js</title>
<style>
.inputoutput{
float: left;
}
</style>
</head>
<body>
<h2>Program of OpenCV.js</h2>
<p id="status">OpenCV.js is loading...</p>
<div>
<div class="inputoutput">
<img id="imageSrc" alt="No Image" />
<div class="caption">imageSrc <input type="file" id="fileInput" name="file" /></div>
</div>
<div class="inputoutput">
<canvas id="canvasOutput" ></canvas>
<div class="caption">canvasOutput</div>
</div>
</div>
<script type="text/javascript">
var imgSrcElement=document.getElementById('imageSrc');
var imageInput=document.getElementById('fileInput');
imageInput.addEventListener('change',(e)=>{
imgSrcElement.src=URL.createObjectURL(e.target.files[0]);
})
// 因为是异步操作,所以需要onload等图像加载完毕后执行,也是回调
imgSrcElement.onload=function(){
// 读取获取矩阵(步骤1)
let mat=cv.imread(imgSrcElement);
// 输出获取矩阵(步骤3)
cv.imshow('canvasOutput',mat);
// 调用delete释放堆的内存
mat.delete();
}
var opencvLoad=function(){
document.getElementById('status').innerHTML='opencv is ready';//回调函数,用来显示opencv.js加载完成
}
</script>
<!-- 异步加载,不对程序进行阻塞 -->
<script async src="opencv.js" onload="opencvLoad()" type="text/javascript"></script>
</body>
</html>