JS.17 アノテーションデータ(バウンディングボックス)作成ツールのコード

2019-09-04(Wed) | tags: tools

アノテーションデータ(バウンディングボックス)作成ツールのコードを簡単に解説します。

ディレクトリを受け取る

これは非常に簡単で、<input> タグに webkitdirectory と書けばそれで終了です。

<input id="ex1" type="file" webkitdirectory>

なお、以下のようにすれば、ディレクトリの各種情報を得ることができます。

document.getElementById('ex1').addEventListener('change', function(e){
  dir = e.target.files; // これでディレクトリを受け取る。
  dirname = dir[0].webkitRelativePath; // 一つめのファイルのパス
  filenum = dir.length; // ファイルの数
});

マウスの座標を可視化する。

<canvas id="ex2" width="200px" height="200px" style="border: 1.5px solid #000; background-color: #eee"></canvas>
<script>
  window.addEventListener('load', function() {
    var Canvas = document.getElementById('ex2');
    var Context = Canvas.getContext('2d');
    Context.strokeStyle = "#0082af";
    Context.lineWidth = 1;

    function ex2draw(x,y){
      Context.clearRect(0, 0, Canvas.width, Canvas.height);

      // Draw Indicator.
      Context.beginPath();

      Context.moveTo(0, y);
      Context.lineTo(Canvas.width, y);

      Context.moveTo(x, 0);
      Context.lineTo(x, Canvas.height);

      Context.closePath();
      Context.stroke();
    }

    Canvas.addEventListener('mousemove', function(e) {
      ex2draw(e.layerX, e.layerY);
    });
  });
</script>

<canvas> には、Context.beginPath() から Context.closePath() までに描いたものが Context.stroke() によって描かれます。

バウンディングボックスを描く

<canvas id="ex3" width="200px" height="200px" style="border: 1.5px solid #000; background-color: #fff"></canvas>
<script>
  var Canvas;
  var Context;
  var RectEdgeColor = "#FB0";
  var RectInnerColor = "rgba(255,230,174,0.3)";
  var IndicatorColor = "#0082af";
  var index=0;
  var DrawingMemory = { 0: { x: null, y: null, w: null, h: null} };
  window.addEventListener('load', function() {
    Canvas = document.getElementById('ex3');
    Context = Canvas.getContext('2d');
    Context.strokeStyle = IndicatorColor;
    Context.fillStyle = RectInnerColor;
    Context.lineWidth = 1;

    var startPosition = { x: null, y: null };
    var isDrag;

    function dragStart(x,y){
      isDrag=true;
      startPosition.x = x;
      startPosition.y = y;
    }

    function dragEnd(x,y){
      if (isDrag){
        DrawingMemory[index] = { x: startPosition.x, y: startPosition.y, w: x-startPosition.x, h: y-startPosition.y };
        index+=1;
        drawFromMemory();
      }else{
        clear();
        drawFromMemory();
      }
      isDrag=false;
    }

    function drawFromMemory(){
      Context.strokeStyle = RectEdgeColor;
      for (i=0; i<index; i++){
        Context.fillRect(DrawingMemory[i].x, DrawingMemory[i].y, DrawingMemory[i].w, DrawingMemory[i].h);
      }
      for (i=0; i<index; i++){
        Context.strokeRect(DrawingMemory[i].x, DrawingMemory[i].y, DrawingMemory[i].w, DrawingMemory[i].h);
      }
      Context.strokeStyle = IndicatorColor;
    }

    function draw(x,y){
      clear(); // Initialization.
      drawFromMemory(); // Draw Bounding Boxes.

      // Draw Indicator.
      Context.beginPath();
      Context.moveTo(0, y); // start
      Context.lineTo(Canvas.width, y); // end
      Context.moveTo(x, 0); // start
      Context.lineTo(x, Canvas.height); // end
      Context.closePath();
      Context.stroke();

      // Draw the current Bounding Box.
      if(isDrag){
        Context.strokeStyle = RectEdgeColor;
        Context.fillRect(startPosition.x, startPosition.y, x-startPosition.x, y-startPosition.y);
        Context.strokeRect(startPosition.x, startPosition.y, x-startPosition.x, y-startPosition.y);
        Context.strokeStyle = IndicatorColor;
      }
    }

    function mouseHandler(){
      Canvas.addEventListener('mousedown', function(e){
        dragStart(e.layerX, e.layerY);
      });
      Canvas.addEventListener('mouseup', function(e){
        dragEnd(e.layerX, e.layerY);
      });
      Canvas.addEventListener('mouseout', function(e){
        dragEnd(e.layerX, e.layerY);
      });
      Canvas.addEventListener('mousemove', function(e) {
        draw(e.layerX, e.layerY);
      });
    }
    mouseHandler();
  });

  function clear(){
    Context.clearRect(0, 0, Canvas.width, Canvas.height);
  }
</script>

あとは、バウンディングボックスの情報を保持して、最後にラベルデータや width,height と一緒に JSON.stringifyjson データにしてダウンロードすれば終了です。

other contents
social