前些生活,老前辈强烈推荐了1个趣味的新项目 —— Real-Time-Person-Removal ,这个新项目应用了 TensorFlow.js ,和 canvas 中的图象解决完成视頻中的角色消退。借此机遇,备考下 canvas 基本中的图象解决。
基本 API
canvas 的图象解决工作能力根据 ImageData 目标来解决像素数据信息。关键的 API 以下:
imageData = { width: Number, height: Number, data: Uint8ClampedArray }
width 是 canvas 画布的宽或说 x 轴的像素数量;height 是画布的高或说 y 轴的像素数量;data 是画布的像素数据信息数字能量数组,总长度 w * h * 4,每 4 个值(rgba)意味着1个像素。
对照片的解决
下面,大家根据几个事例看来下 canvas 基本的照片解决工作能力。
原图实际效果:
const cvs = document.getElementById("canvas"); const ctx = cvs.getContext("2d"); const img = new Image(); img.src="照片 URL"; img.onload = function () { ctx.drawImage(img, 0, 0, w, h); }
底片/负片实际效果
优化算法:将 255 与像素点的 rgb 的差,做为当今值。
function negative(x) { let y = 255 - x; return y; }
实际效果图:
const imageData = ctx.getImageData(0, 0, w, h); const { data } = imageData; let l = data.length; for(let i = 0; i < l; i+=4) { const r = data[i]; const g = data[i + 1]; const b = data[i + 2]; data[i] = negative(r); data[i + 1] = negative(g); data[i + 2] = negative(b); } ctx.putImageData(imageData, 0, 0);
纯色实际效果
纯色实际效果便是保存当今像素的 rgb 3个值中的1个,除去别的色值。
for(let i = 0; i < l; i+=4) { // 除去了 r 、g 的值 data[i] = 0; data[i + 1] = 0; }
实际效果图:
灰度值图
灰度值图:每一个像素仅有1个色值的图象。0 到 255 的色值,色调由黑变白。
for(let i = 0; i < l; i+=4) { const r = data[i]; const g = data[i + 1]; const b = data[i + 2]; const gray = grayFn(r, g, b); data[i] = gray; data[i + 1] = gray; data[i + 2] = gray; }
优化算法1——均值法:
const gray = (r + g + b) / 3;
实际效果图:
优化算法2——人眼认知:依据人眼对红绿蓝3色的认知水平:绿 > 红 > 蓝,给定权重区划
const gray = r * 0.3 + g * 0.59 + b * 0.11
实际效果图:
除此之外,也有:
取最大值或最少值。
const grayMax = Math.max(r, g, b); // 值偏大,较亮 const grayMin = Math.min(r, g, b); // 值偏小,较暗
取单1安全通道,即 rgb 3个值中的1个。
2值图
优化算法:明确1个色值,较为当今的 rgb 值,超过这个值显示信息黑色,不然显示信息白色。
for(let i = 0; i < l; i+=4) { const r = data[i]; const g = data[i + 1]; const b = data[i + 2]; const gray = gray1(r, g, b); const binary = gray > 126 ? 255 : 0; data[i] = binary; data[i + 1] = binary; data[i + 2] = binary; }
实际效果图:
高斯模糊不清
高斯模糊不清是“模糊不清”优化算法中的1种,每一个像素的值全是周边邻近像素值的加权均值。初始像素的值有最大的高斯遍布值(有最大的权重),邻近像素伴随着间距初始像素愈来愈远,权重也愈来愈小。
1阶公式:
(应用1阶公式是由于1阶公式的优化算法较为简易)
const radius = 5; // 模糊不清半径 const weightMatrix = generateWeightMatrix(radius); // 权重引流矩阵 for(let y = 0; y < h; y++) { for(let x = 0; x < w; x++) { let [r, g, b] = [0, 0, 0]; let sum = 0; let k = (y * w + x) * 4; for(let i = -radius; i <= radius; i++) { let x1 = x + i; if(x1 >= 0 && x1 < w) { let j = (y * w + x1) * 4; r += data[j] * weightMatrix[i + radius]; g += data[j + 1] * weightMatrix[i + radius]; b += data[j + 2] * weightMatrix[i + radius]; sum += weightMatrix[i + radius]; } } data[k] = r / sum; data[k + 1] = g / sum; data[k + 2] = b / sum; } } for(let x = 0; x < w; x++) { for(let y = 0; y < h; y++) { let [r, g, b] = [0, 0, 0]; let sum = 0; let k = (y * w + x) * 4; for(let i = -radius; i <= radius; i++) { let y1 = y + i; if(y1 >= 0 && y1 < h) { let j = (y1 * w + x) * 4; r += data[j] * weightMatrix[i + radius]; g += data[j + 1] * weightMatrix[i + radius]; b += data[j + 2] * weightMatrix[i + radius]; sum += weightMatrix[i + radius]; } } data[k] = r / sum; data[k + 1] = g / sum; data[k + 2] = b / sum; } } function generateWeightMatrix(radius = 1, sigma) { // sigma 标准正态分布的规范误差 const a = 1 / (Math.sqrt(2 * Math.PI) * sigma); const b = - 1 / (2 * Math.pow(sigma, 2)); let weight, weightSum = 0, weightMatrix = []; for (let i = -radius; i <= radius; i++){ weight = a * Math.exp(b * Math.pow(i, 2)); weightMatrix.push(weight); weightSum += weight; } return weightMatrix.map(item => item / weightSum); // 归1解决 }
实际效果图:
别的实际效果
这里再简易详细介绍下别的的图象实际效果解决,由于事例简易反复,因此已不得出编码和实际效果图。
总结
好了,上面便是1些基本的图象解决优化算法。
参照材料
高斯模糊不清的优化算法
高斯模糊不清
到此这篇有关canvas 基本之图象解决的应用的文章内容就详细介绍到这了,更多有关canvas 图象解决內容请检索脚本制作之家之前的文章内容或再次访问下面的有关文章内容,期待大伙儿之后多多适用脚本制作之家!