先贴个源码然后睡觉,有事后面再说吧!`<!DOCTYPE html>
<html lang="zh-cn">
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>手写体数字识别</title> <style> canvas { outline: 1px solid #000; } </style></head>
<body> <div style="float:left;padding: 20px"> <!-- 手写数字画板 --> <canvas width="640" height="480" id="canvas"></canvas> <p> <button id="clear" style="float: left;">清空画布</button> <button id="start_count" style="float: right;">开始计算</button> </p> </div> <div style="float: left;padding: 20px;width: 50%;"> <!-- 预处理后的图片展示 --> <div> <canvas width="28" height="28" id="exhibition_booth" style="width: 256px;height:256px;"> </canvas> <span style="font-size: 300px;padding-left: 50px" id="result_box"></span> </div> <p> <div>预测结果:</div> <div id="result_box"></div> </p> <p> <p><input type="text" id="input"></p> <p><button id="btn">提交</button></p> </p> <p> <div>预测结果:</div> <div> <table> <thead> <tr> <th width="300">结果</th> <th width="500">概率</th> </tr> </thead> <tbody id="tb"> </tbody> </table> </div> </p> </div></body><script> //获取手写数字画板 const canvas = document.getElementById('canvas'); const cact = canvas.getContext('2d'); const canvasWidth = 640; const canvasHeight = 480; cact.lineWidth = 30; cact.lineJoin = 'round'; cact.imageSmoothingEnabled = false;
//获取与处理结果输出画板
const exhibition_booth = document.getElementById('exhibition_booth');
const ebct = exhibition_booth.getContext('2d');
ebct.imageSmoothingEnabled = false;
const start_count = document.getElementById('start_count');
const data_box = document.getElementById('data_box');
const input = document.getElementById('input');
const btn = document.getElementById('btn');
const result_box = document.getElementById('result_box');
const tb = document.getElementById('tb');
let dataAggregation = {};
let studyCountAggregation = {};
let nowData = null;
input.onfocus = function () {
input.value = '';
}
start_count.onclick = function () {
result_box.innerText = '';
//清空小画布
ebct.clearRect(0, 0, 28, 28);
let { data } = cact.getImageData(0, 0, canvasWidth, canvasHeight);
let minX = Infinity, minY = Infinity, maxX = 0, maxY = 0;
//计算图片四个边沿的尺寸
for (let i = 0; i < data.length; i += 3) {
let nowPixel = data[i];
if (nowPixel) {
const nowX = (i + 1) / 4 % canvasWidth;
const nowY = ((i + 1) / 4) / canvasWidth;
if (nowX < minX) {
minX = nowX;
}
if (nowY < minY) {
minY = nowY;
}
if (nowX > maxX) {
maxX = nowX;
}
if (nowY > maxY) {
maxY = nowY;
}
}
}
let imgX = Math.ceil(minX);
let imgY = Math.ceil(minY);
let imgWidth = Math.ceil(maxX - minX);
let imgHeight = Math.ceil(maxY - minY);
let diff = Math.abs(imgWidth - imgHeight);
if (diff) {
if (imgWidth > imgHeight) {
imgY -= diff / 2;
imgHeight += diff;
} else {
imgX -= diff / 2;
imgWidth += diff;
}
}
// cact.lineWidth = 1;
// cact.strokeRect(imgX, imgY, imgWidth, imgHeight);
// cact.lineWidth = 30;
//把大画布上的图片缩放之后复制到小画布上
ebct.drawImage(canvas, imgX, imgY, imgWidth, imgHeight, 0, 0, 28, 28);
//获取小画布上的所有像素点
({ data } = ebct.getImageData(0, 0, 28, 28));
//展开成784个元素的一维数组(28*28的宽度)
let list = [];
for (let i = 0; i < data.length; i += 4) {
let nowPixel = data[i - 1];
if (nowPixel) {
list.push(1);
} else {
list.push(0);
}
}
nowData = list;
return doForecast(list);
}
btn.onclick = function () {
const text = input.value;
if (nowData) {
doStudy(text, nowData);
start_count.onclick();
let { result, probability } = doForecast(nowData);
let i = 0;
while (result != text) {
({ result, probability } = doForecast(nowData));
i++;
if (i >= 100) {
alert('100次都学不会,还学个鸡儿!')
break
};
}
console.log(result);
}
}
function doForecast(list) {
let i = 0;
let forecastResult = [];
let probabilitySum = 0;
let additionalProbability = 0;
for (let result in dataAggregation) {
let data = dataAggregation[result];
let num = 0;
for (let i = 0; i < list.length; i++) {
let score = -(data[i] / studyCountAggregation[result]);
if (list[i] == 0) {
num += score;
} else {
num -= score;
}
}
let probability = (num / 784) * 100;
if (probability < 0) {
additionalProbability -= probability;
probability = 0;
}
if (probability > 100) {
probability = 100;
}
forecastResult.push({
'result': result
, 'probability': probability
});
probabilitySum += probability;
i++;
}
forecastResult.sort(function (a, b) {
return b.probability - a.probability;
});
tb.innerHTML = '';
forecastResult.forEach(function (data) {
const result = data.result;
let probability = data.probability;
const tr = document.createElement('tr');
const td1 = document.createElement('td');
const td2 = document.createElement('td');
td1.innerText = result;
td2.innerText = probability + '%';
tr.appendChild(td1);
tr.appendChild(td2);
tb.appendChild(tr);
})
let result, probability;
if (forecastResult[0]) {
result = forecastResult[0].result;
probability = forecastResult[0].probability
}
if (result) {
result_box.innerText = result;
}
if (i == 0) {
alert('数据集空空如也,请告诉我这是什么!');
}
return { result, probability };
}
function doStudy(result, data) {
if (result in dataAggregation) {
const data2 = dataAggregation[result];
if (data2.length !== data.length) {
alert('数据长度不一致')
return;
}
studyCountAggregation[result]++;
for (let i = 0; i < data.length; i++) {
if (data[i]) {
data2[i] = data2[i] + 1;
} else {
data2[i] = data2[i] - 1;
}
}
} else {
dataAggregation[result] = [];
studyCountAggregation[result] = 1;
for (let i = 0; i < data.length; i++) {
if (data[i]) {
dataAggregation[result].push(1);
} else {
dataAggregation[result].push(-1);
}
}
}
for (let key in dataAggregation) {
if (key == result) continue;
const data3 = dataAggregation[key];
for (let i = 0; i < data.length; i++) {
if (data[i]) {
data3[i] = data3[i] - 0.05;
} else {
data3[i] = data3[i] + 0.05;
}
}
studyCountAggregation[key] += 0.05;
}
}
//清除按钮,点击清空画板
const clearBtn = document.getElementById('clear');
clearBtn.onclick = function () {
tb.innerHTML = '';
result_box.innerText = '';
cact.clearRect(0, 0, 640, 480);
ebct.clearRect(0, 0, 640, 480);
}
//下面是手写画板的事件绑定
let startPainting = false;
canvas.onmousedown = function (e) {
const { offsetX, offsetY } = e;
cact.beginPath();
cact.moveTo(offsetX, offsetY);
startPainting = true;
}
let lastMouseCoordinate = {
offsetX: 0
, offsetY: 0
}
canvas.onmousemove = function (e) {
const { offsetX, offsetY } = e;
if (startPainting) {
const { offsetX: lastX, offsetY: lastY } = lastMouseCoordinate;
if (lastX + lastY) {
cact.moveTo(lastX, lastY);
}
lastMouseCoordinate = { offsetX, offsetY }
cact.lineTo(offsetX, offsetY);
cact.closePath();
cact.stroke();
}
}
canvas.onmouseup = function (e) {
const { offsetX, offsetY } = e;
startPainting = false
lastMouseCoordinate = {
offsetX: 0
, offsetY: 0
}
}
document.onmousemove = function (e) {
if (e.target != canvas) {
canvas.onmouseup.call(this, e);
}
}
</script>
</html>`