OpenCVで動画を描画

このエントリーをはてなブックマークに追加

How it works

opencv.jsはOpencvのjs実装です。
これを使って、カメラ画像をCannyエッヂ検出し、obnizのOLEDに描画しています。

Program

<!-- HTML Example -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <script src="https://docs.opencv.org/3.4/opencv.js"></script>
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@1.2.1/obniz.js"></script>
</head>
<body>

<div id="obniz-debug"></div>
  
<div><div class="control"><button id="startAndStop">Start</button></div></div>
<p class="err" id="errorMessage"></p>
<div>
    <table cellpadding="0" cellspacing="0" width="0" border="0">
    <tr>
        <td>
            <video id="videoInput" width=320 height=240></video>
        </td>
        <td>
            <canvas id="canvasOutput" width=128 height=64 style="-webkit-font-smoothing:none"></canvas>
        </td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <td>
            <div class="caption">videoInput</div>
        </td>
        <td>
            <div class="caption">canvasOutput</div>
        </td>
        <td></td>
        <td></td>
    </tr>
    </table>
</div>
  
<script src="https://webrtc.github.io/adapter/adapter-5.0.4.js" type="text/javascript"></script>
<script src="https://docs.opencv.org/3.4/utils.js" type="text/javascript"></script>
<script type="text/javascript">

obniz = new Obniz("OBNIZ_ID_HERE");

obniz.onconnect = async () => {
  obniz.display.print("ready")
}
  
let utils = new Utils('errorMessage');

let streaming = false;
let videoInput = document.getElementById('videoInput');
let startAndStop = document.getElementById('startAndStop');
let canvasOutput = document.getElementById('canvasOutput');
let canvasContext = canvasOutput.getContext('2d');

startAndStop.addEventListener('click', () => {
    if (!streaming) {
        utils.clearError();
        utils.startCamera('qvga', onVideoStarted, 'videoInput');
    } else {
        utils.stopCamera();
        onVideoStopped();
    }
});

function onVideoStarted() {
    streaming = true;
    startAndStop.innerText = 'Stop';
    videoInput.width = videoInput.videoWidth;
    videoInput.height = videoInput.videoHeight;
    start();
}

function onVideoStopped() {
    streaming = false;
    canvasContext.clearRect(0, 0, canvasOutput.width, canvasOutput.height);
    startAndStop.innerText = 'Start';
}

function start() {
  let video = document.getElementById('videoInput');
  let src = new cv.Mat(video.height, video.width, cv.CV_8UC4);
  let dst = new cv.Mat();
  let cap = new cv.VideoCapture(video);

  const FPS = 20;
  function processVideo() {
    if (!streaming) {
      src.delete();
      dst.delete();
      return;
    }
    let begin = Date.now();

    cap.read(src);
    cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY);
    cv.Canny(dst, dst, 50, 100, 3, false);
    let dsize = new cv.Size(128, 64);
    cv.resize(dst, dst, dsize, 0, 0, cv.INTER_AREA);
    cv.threshold(dst, dst, 50, 255, cv.THRESH_BINARY);
    cv.imshow('canvasOutput', dst);

    let delay = 1000/FPS - (Date.now() - begin);
    setTimeout(processVideo, delay);

    let ctx = $("#canvasOutput")[0].getContext('2d');
    obniz.display.draw(ctx)
  };

  setTimeout(processVideo, 0);
}
</script>
</body>
</html>

今すぐ実行

HTMLがブラウザで開かれて実行されます。