目标:了解如何阅读图像以及如何在网络中显示它。
读取图像:OpenCV.js 将图像保存为cv.Mat类型。我们使用 HTML 画布元素将cv.Mat传输到网络或反向传输。ImageData 接口可以表示或设置画布元素区域的底层像素数据。
1.从画布创建一个 ImageData对象
let canvas = document.getElementById(canvasInputId);
let ctx = canvas.getContext('2d');
let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
2.使用 cv.matFromImageData 构造一个cv.Mat
let src = cv.matFromImageData(imgData);
note:因为canvas只支持连续存储的8位RGBA图像,所以cv.Mat类型为cv.CV_8UC4。它与原生 OpenCV 不同,因为原生imread和imshow返回和显示的图像具有按 BGR 顺序存储的通道。
显示图像:
1.首先将src的类型转换为cv.CV_8UC4
let dst = new cv.Mat();
// scale and shift are used to map the data to [0, 255].
src.convertTo(dst, cv.CV_8U, scale, shift);
// *** is GRAY, RGB, or RGBA, according to src.channels() is 1, 3 or 4.
cv.cvtColor(dst, dst, cv.COLOR_***2RGBA);
2.从 dst 新建一个 ImageData
let imgData = new ImageData(new Uint8ClampedArray(dst.data, dst.cols, dst.rows);
3.显示它
let canvas = document.getElementById(canvasOutputId);
let ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = imgData.width;
canvas.height = imgData.height;
ctx.putImageData(imgData, 0, 0);
在 OpenCV.js 中
Parameters参数
imageSource | canvas element or id, or img element or id. |
Returns返回
具有以 RGBA 顺序存储的通道的垫子(mat)。
我们使用cv.imshow (canvasSource, mat)来显示它。该函数可以根据垫子(mat)的深度缩放垫子(scale the mat):
- 如果 mat 是 8 位无符号的,则按原样显示。
- 如果 mat 是 16 位无符号或 32 位整数,则像素除以 256。即取值范围 [0,255*256] 映射到 [0,255]。
- 如果 mat 是 32 位浮点,则像素值乘以 255。即值范围 [0,1] 映射到 [0,255]。
参数
canvasSource | canvas element or id. |
mat | mat to be shown. |
上面的图像读取和显示代码可以简化如下:
let img = cv.imread(imageSource);
cv.imshow(canvasOutput, img);
img.delete();
核心代码:
let src = cv.imread('canvasInput');
let dst = new cv.Mat();
// To distinguish the input and output, we graying the image.
// You can try different conversions.
cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY);
cv.imshow('canvasOutput', dst);
src.delete();
dst.delete();
完整代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello OpenCV.js</title>
</head>
<body>
<h2>Hello 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">
let imgElement = document.getElementById('imageSrc');
let inputElement = document.getElementById('fileInput');
inputElement.addEventListener('change', (e) => {
imgElement.src = URL.createObjectURL(e.target.files[0]);
}, false);
imgElement.onload = function() {
let src = cv.imread(imgElement);
let dst = new cv.Mat();
// To distinguish the input and output, we graying the image.
// You can try different conversions.
cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY);
cv.imshow('canvasOutput', dst);
src.delete();
dst.delete();
};
function onOpenCvReady() {
document.getElementById('status').innerHTML = 'OpenCV.js is ready.';
}
</script>
<script async src="opencv.js" onload="onOpenCvReady();" type="text/javascript"></script>
</body>
</html>
结果: