Skip to content

Instantly share code, notes, and snippets.

@leaysgur
Last active October 28, 2018 06:14
Show Gist options
  • Save leaysgur/cb148c13cdc6009df87859fed51f7e4b to your computer and use it in GitHub Desktop.
Save leaysgur/cb148c13cdc6009df87859fed51f7e4b to your computer and use it in GitHub Desktop.
import pixelmatch from './pixelmatch.js';
const W = 640 / 2;
const H = 480 / 2;
main().catch(console.error);
async function main() {
// アプリの画面をつくる
const { $video, $setupButton, $diffButton } = initView();
// カメラ映像をとってくる
const stream = await getCameraStream();
// 表示
$video.srcObject = stream;
await $video.play();
let bgImg;
// まず背景を保存
$setupButton.addEventListener('click', async () => {
$setupButton.disabled = true;
$diffButton.disabled = false;
bgImg = getImageData($video);
});
$diffButton.addEventListener('click', async () => {
$diffButton.disabled = true;
const $canvas = document.createElement('canvas');
$canvas.width = W;
$canvas.height = H;
const diffCtx = $canvas.getContext('2d');
document.body.appendChild($canvas);
render();
function render() {
requestAnimationFrame(render);
const img = getImageData($video);
// その差分を pixelmatch
const diff = diffCtx.createImageData(W, H);
// threshold の設定がシビア、キツいと明るさで差分がめっちゃ出るし、ゆるいと皮膚が壁と同化する
pixelmatch(bgImg.data, img.data, diff.data, W, H, { threshold: .25 });
// 差分を画面に表示
diffCtx.putImageData(diff, 0, 0);
}
});
}
function initView() {
const $video = document.createElement('video');
$video.width = W;
$video.height = H;
const $setupButton = document.createElement('button');
$setupButton.textContent = 'Setup';
const $diffButton = document.createElement('button');
$diffButton.textContent = 'Diff';
$diffButton.disabled = true;
const $root = document.getElementById('root');
$root.appendChild($video);
$root.appendChild(document.createElement('hr'));
$root.appendChild($setupButton);
$root.appendChild($diffButton);
$root.appendChild(document.createElement('hr'));
return { $video, $setupButton, $diffButton };
}
async function getCameraStream() {
await navigator.mediaDevices.getUserMedia({ video: true });
const devices = await navigator.mediaDevices.enumerateDevices();
const [camera] = devices.filter(d => d.kind === 'videoinput' && /camera/i.test(d.label));
const stream = await navigator.mediaDevices.getUserMedia({ video: { deviceId: camera.deviceId } });
return stream;
}
function getImageData($video) {
const $canvas = document.createElement('canvas');
$canvas.width = W;
$canvas.height = H;
const ctx = $canvas.getContext('2d');
ctx.drawImage($video, 0, 0, W, H);
const imageData = ctx.getImageData(0, 0, W, H);
return imageData;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment