验证画布绘图

时间:2014-03-09 12:44:01

标签: javascript html html5 canvas drawing

我使用HTML5 Canvas制作了这个小图纸 app ,孩子们可以在这里学习如何写字母和数字。我想知道是否正确绘制了字母/数字。

我尝试做this之类的事情来检测简单的直线,比如数字'1'。

但我无法弄清楚如何检测复杂的形状,如数字'2','8'(以及除直线之外的其他任何东西)

帮助?

2 个答案:

答案 0 :(得分:2)

如果你只是想给他们写下“2”的肌肉记忆,那么你可以在画布上画上“2”的轮廓并让它们填充那个轮廓。

如果轮廓内部的鼠标点多于外部,那么它们可能会画出轮廓。

但是,要“回忆”一个数字并将其写入画布,您就需要进行字符识别(!)。

我只是用谷歌搜索,发现这个有趣的数字识别尝试。

http://www.heatonresearch.com/fun/ocr

[更新:简单“留在线下”游戏的例子]

以下是游戏的运作方式:

  • 在画布上用白色填充描绘数字“2”的轮廓
  • 使用context.getImageData
  • 保存像素数组
  • “2”内的像素将具有alpha> 20
  • “2”之外的像素将具有α<20
  • 让孩子们将鼠标拖到“2”
  • 收听mousemove活动
  • 测试鼠标下像素的alpha值
  • (α<20表示外部α> 20表示“2”内部)
  • 如果他们在“2”内,则将他们的分数加1
  • 如果他们在“2”之外,则从他们的分数中减去1
  • (可选)如果“2”为绿色,则将其作为正确的视觉反馈

当他们释放鼠标时,会出现他们的分数。分数表示鼠标内部减去鼠标数量。

以下是示例代码和演示:http://jsfiddle.net/m1erickson/LL6ba/

鼠标在数字内部 - 正面视觉反馈的数字为绿色

enter image description here

鼠标数字以外 - 没有正面的视觉反馈

enter image description here

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: white; }
    #canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var $canvas=$("#canvas");
    var canvasOffset=$canvas.offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var scrollX=$canvas.scrollLeft();
    var scrollY=$canvas.scrollTop();


    ctx.font="216px arial";
    ctx.fillStyle="white";
    ctx.fillText("2",100,200);
    ctx.strokeText("2",100,200);

    var cw=canvas.width;
    var ch=canvas.height;
    var imgData=ctx.getImageData(0,0,cw,ch);
    var data=imgData.data;

    var isDown=false;
    var wasInside=true;
    var score=0;

    function draw(mouseX,mouseY){

        var alpha = data[((cw*mouseY)+mouseX)*4+3];

        score+=(alpha>19?1:-1);

        if(alpha<20 && wasInside){
            wasInside=false;
            ctx.fillStyle="white";
            ctx.fillRect(0,0,cw,ch);
            ctx.fillStyle="white";
            ctx.fillText("2",100,200);
            ctx.strokeText("2",100,200);
        }else if(alpha>19 && !wasInside){
            wasInside=true;
            ctx.fillStyle="white";
            ctx.fillRect(0,0,cw,ch);
            ctx.fillStyle="green";
            ctx.fillText("2",100,200);
            ctx.strokeText("2",100,200);
        }

    }

    function handleMouseDown(e){
      e.preventDefault();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      var alpha = data[((cw*mouseY)+mouseX)*4+3];
      wasInside=(alpha<20);
      score=0;
      isDown=true;
      draw(mouseX,mouseY);
    }

    function handleMouseUp(e){
      e.preventDefault();
      isDown=false;
      $("#score").text("Score: "+score);
    }

    function handleMouseOut(e){
      e.preventDefault();
      isDown=false;
    }

    function handleMouseMove(e){
      if(!isDown){return;}
      e.preventDefault();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      draw(mouseX,mouseY);
    }

    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUp(e);});
    $("#canvas").mouseout(function(e){handleMouseOut(e);});

}); // end $(function(){});
</script>

</head>

<body>
    <h4>Drag inside the number<br>Number stays green while you're inside.</h4>
    <h3 id="score">Score:</h3>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

答案 1 :(得分:1)

这是一个复杂的领域,可能超出SO的范围,但要研究神经网络或在线识别(当他们画画时)。

这是一种神经网络方法(C ++中的源代码;应该有点容易转换为JavaScript)(它带有一个重量文件):
Neural Network for Recognition of Handwritten Digits

这是一种使用多卷积神经网络(C#代码)的在线方法:
Online handwriting recognition using multi convolution neural networks

有关该主题的更多信息:
https://en.wikipedia.org/wiki/Handwriting_movement_analysis
https://en.wikipedia.org/wiki/Handwriting_recognition