Last active
October 28, 2018 06:14
-
-
Save leaysgur/cb148c13cdc6009df87859fed51f7e4b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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