html canvas 图像边缘提取,在HTML5 canvas里用卷积核进行图像处理

卷积

什么是卷积?

就跳过一些用专业属于描述专业术语看完懵逼的解释了,

语文成绩很差的我尝试从字面解释什么是卷积...

卷,理解成一种压缩;积,乘积,积累;

卷积需要一个卷积核,通常是3x3或5x5的方阵,

例如这样

// 一个3x3卷积核

0 0 0

0 1 0

0 0 0

我们要怎么用卷积核处理数据呢?

下面是一个例子:

// 下面是一堆排成方阵的数据

// 这是我们的数据源

1 3 5 1 3 5 1 3 5

4 5 6 1 3 5 1 3 5

4 5 6 1 3 5 1 3 5

4 5 6 1 3 5 1 3 5

我们将要用卷积核“扫描并处理”每一个数据,

例如要处理第二行第二列的5

1 3 5 0 0 0

4 5 6 * 0 1 0

4 5 6 0 0 0

我们把5周围的数字抽出来,然后把两个方阵位置相同的数字相乘然后相加,

得出5,这是当然的,因为这个卷积核做的就是输出原数据?

-1 -1 -1

-1 8 -1

-1 -1 -1

同样的原理,试试另一个不同的卷积核

1 3 5 -1 -1 -1

4 5 6 * -1 8 -1

4 5 6 -1 -1 -1

我们得到的是

1*-1 + 3*-1 + 5*-1

+ 4*-1 + 5*8 + 6*-1

+ 4*-1 + 5*-1 + 6*-1

= 6

然后用得出来的6放入原来5的位置,就是这样“扫描并处理”每一个数据

边缘怎么办?

常数填充

复制边缘像素

突然的深度拓展

卷积在深度学习中十分重要,下面是一个可视化CNN(卷积神经网络)的卷积过程

http://scs.ryerson.ca/~aharle...

canvas

是一个可以使用脚本(通常为JavaScript)来绘制图形的 HTML 元素.它可以用于绘制图表、制作图片构图或者制作简单的(以及不那么简单的)动画。

canvas 绘制图片

ctx.drawImage(image, x, y)

bV9Nf1?w=684&h=364

canvas 转换为 ImageData

ctx.getImageData(sx, sy, sw, sh);

// 返回 ImageData

ImageData 数据是 Uint8ClampedArray ,它描述了一个一维数组,包含以 RGBA 顺序的数据,数据使用 0 至 255(包含)的整数表示。

所以每一个点都会表示为:

// 这样仅仅是一个像素点的数据

R G B A

255 255 0 255

卷积 + ImageData = ?

图像归根到底就是一大堆的颜色点矩阵,我们完全可以把颜色点代替上面的数字矩阵处理,

不同的卷积核对图片的处理结果如下(图片来自维基百科)

1460000014679654?w=487&h=606

卷积就是如此神奇?

在 canvas 中实现卷积处理

以下是一个 JavaScript 对 canvas 输出的 ImageData 进行卷积的实例:

/*

* 参数中的 kernel 就是卷积核方阵,不过顺着排列成了一个九位的数组

* 像是这样 [-1, -1, -1, -1, 8, -1, -1, -1, -1]

* offset 对RGBA数值直接增加,表现为提高亮度

* 下面的for循环

* y 代表行,x 代表列,c 代表RGBA

*/

convolutionMatrix(input, kernel, offset = 0) {

let ctx = this.outputCtx

let output = ctx.createImageData(input)

let w = input.width,

h = input.height

let iD = input.data,

oD = output.data

for (let y = 1; y < h - 1; y += 1) {

for (let x = 1; x < w - 1; x += 1) {

for (let c = 0; c < 3; c += 1) {

let i = (y * w + x) * 4 + c

oD[i] =

offset +

(kernel[0] * iD[i - w * 4 - 4] +

kernel[1] * iD[i - w * 4] +

kernel[2] * iD[i - w * 4 + 4] +

kernel[3] * iD[i - 4] +

kernel[4] * iD[i] +

kernel[5] * iD[i + 4] +

kernel[6] * iD[i + w * 4 - 4] +

kernel[7] * iD[i + w * 4] +

kernel[8] * iD[i + w * 4 + 4]) /

this.divisor

}

oD[(y * w + x) * 4 + 3] = 255

}

}

ctx.putImageData(output, 0, 0)

}

成品代码

测试网址,附带彩蛋嘻嘻嘻?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值