创建一个轨道条可以用于参数的动态调节,在实际操作中是非常高效、重要的,HTML 我们可以使用原生的 <input type=‘range’> 创建Trackbar <input value="50" min="0" max="100" step="1" id="trackBar" type="range"/>
,本例使用 addWeighted
方法展示Trackbar,该方法用于两个图像的权重合成
图像输入
先创建两个canvas 标签用于图像的载入,一个canvas 标签用于图像的输出
<h2>create track bar</h2>
<p id='errMessage'></p>
<input value="50" min="0" max="100" step="1" id="trackBar" type="range"/>
<label id="trackWeight"></label>
<span id="opencvIsReady">opencv is loading</span>
<table>
<tr>
<td><canvas id="canvasInput1"></canvas></td>
<td><canvas id="canvasInput2"></canvas></td>
<td><canvas id="canvasOutput1"></canvas></td>
</tr>
<tr>
<td><div>canvas input1</div> </td>
<td><div>canvas input2</div> </td>
<td><div>canvas output</div> </td>
</tr>
</table>
使用utils 的onloadImageToCanvas
方法加载图像到canvas 中,该就是把过程包装了下,具体如下:
this.loadImageToCanvas = function(url, canvasId) {
let canvas = document.getElementById(canvasId);
let ctx=canvas.getContext('2d')
let img = new Image();
//跨域设置
img.crossorigin = 'anonymous';
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
};
img.src = url;
};
//用于显示错误信息
let utils=new Utils('errMessage')
utils.loadImageToCanvas("/img/hello.jpg","canvasInput1")
utils.loadImageToCanvas("/img/dog.jpg","canvasInput2")
图像合成
接下来的就是再Trackbar 改变的时候读取,合成再输出了,注意再完成过后要对创建的Mat 清除
trackBar.addEventListener('input',(e)=>{
// console.log(trackBar.value)
trackWeight.innerText=trackBar.value
let alpha=(1-trackBar.value/trackBar.max)
let beta=1-alpha
let src1=cv.imread('canvasInput1')
let src2=cv.imread('canvasInput2')
let dst=new cv.Mat()
// 计算公式 src1*alpha+src*beta+gamma 最后一个为深度输出与输入深度相同
cv.addWeighted(src1,alpha,src2,beta,0.0,dst,-1)
cv.imshow('canvasOutput1',dst)
dst.delete()
src1.delete()
src2.delete()
})
效果:
跨域问题
如果单独执行上述代码,在改变 Trackbar 时会报错的,提示
"Uncaught DOMException: Failed to execute ‘getImageData’ on ‘CanvasRenderingContext2D’: The canvas has been tainted by cross-origin data.
这是浏览器对我们网站进行保护的一种措施,当在使用html5的canvas是,当用到getImageData
方法获取图片信息时,会碰到跨域无法获取的情况,主要原因是我们进行本地调试时,图片是是没有域名的,使用getImageData
方法就会报需要跨域的错误,具体解决方法就是将图片和客户端放在同一服务器下,我使用的是node 服务器,使用express 框架,如下:
const express=require('express')
const app=express()
const fs=require('fs')
app.use('/img',express.static('./img'))
app.use('/opencv.js',express.static('./opencv.js'))
app.use('/utils.js',express.static('./utils.js'))
app.get('/',function(req,res){
// res.send(data)
res.sendFile('C://Users/小钢炮/Desktop/test/test.html')
})
app.listen(3000)