往期的4篇已经把 Docker+Keras+Flask+JS 的全栈+深度学习介绍完整了:
今天更新一篇关于: 图像处理 。
再回顾下 MNIST手写字数据集 的特点:每个数据经过 归一化 处理,对应一张 灰度 图片,图片以像素的 重心居中 处理, 28x28 的尺寸。
上一篇文章中,对canvas手写对数字仅做了简单对居中处理,严格来说,应该做一个重心居中的处理。今天就介绍下:
如何实现前端的手写数字按重心居中处理成28x28的图片格式 。
我们先把前端canvas中的手写数字处理成二值图,求重心主要运用了二值图的一阶矩,先来看下零阶矩:
二值图在某点上的灰度值只有0或者1两个值,因此零阶矩为二值图的白色面积总和。
只要把上文的公式转为JS代码,即可求出重心坐标:
SignaturePad.prototype.getGravityCenter = function() { var w = this._ctx.canvas.width, h = this._ctx.canvas.height; var mM = 0, mX = 0, mY = 0; var imgData = this._ctx.getImageData(0, 0, w, h); for (var i = 0; i < imgData.data.length; i += 4) { var t = imgData.data[i + 3] / 255; var pos = this.pixel2Pos(i); mM = mM + t; mX = pos.x * t + mX; mY = pos.y * t + mY; }; var center = { x: mX / mM, y: mY / mM } return center };
pixel2Pos是我另外写的根据i求出点坐标的函数:
SignaturePad.prototype.pixel2Pos = function(p) { var w = this._ctx.canvas.width, h = this._ctx.canvas.height; var y = Math.ceil((p + 1) / 4 / w); var x = Math.ceil((p + 1) / 4 - (y - 1) * w); return { x: x, y: y } }
这里要注意下:
getImageData() 方法返回 ImageData 对象,该对象拷贝了画布指定矩形的像素数据。
对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:
-
R - 红色 (0-255)
-
G - 绿色 (0-255)
-
B - 蓝色 (0-255)
-
A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的)
根据以上的代码就可以找出重心,如下图红点所示位置:
以重心为中心,把数字放置于28x28的正方形中,剪切出来,传给后端即可。
今天就到这里。
近期热文:
码字不易,开启新的打赏方式:
本公众号定期更新关于
设计师、程序员发挥创意
互相融合的指南、作品。
主要技术栈:
nodejs、react native、electron
Elasticsearch
Solidity
Keras
欢迎关注,转发~
欢迎长按二维码
关注本号
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。