ブラウザでカメラ映像から色を判別するときに利用したチップスをメモ
ウェブカメラ動画の取得
videoタグ配置しJSでカメラ取得
※localhost,127.0.0.1 や HTTPS の環境がないと動作しないでした。。
<video id="videoInput" width="640" height="480" autoplay></video>
var video = document.getElementById('videoInput')
navigator.mediaDevices.getUserMedia({
video: {
facingMode: "environment",
},
audio: false,
})
.then(function (stream) {
video.srcObject = stream;
video.play();
})
.catch(function (err) {
console.error(err);
});
カンバスへ変換(描画)
HTMLでカンバスを設置
<canvas id="canvasOutputVideo" width="640" height="480"></canvas>
IntervalでVideoタグの内容をカンバスへ描画
var canvas = document.getElementById("canvasOutputVideo");
var context = canvas.getContext("2d");
setInterval(updateCap, 100);
function updateCap() {
context.drawImage(video, 0, 0, 640, 480);
};
タッチ箇所の取得
下記のどれかで取得となるはず
console.log("screen:" + e.screenX + "," + e.screenY);
console.log("client:" + e.clientX + "," + e.clientY);
console.log("offset:" + e.offsetX + "," + e.offsetY);
平均の色を取得
クリック箇所を中心に3*3の9ドットの平均を算出
カンバスから取得
let imageData = document.getElementById("videoCanvas").getContext("2d").getImageData(click.x-1 , click.y-1 , 3, 3);
let rgba = [0, 0, 0, 0];
imageData.data.forEach((v, i) => {
rgba[i % 4] = rgba[i % 4] + v
});
const r = rgba[0] / (iW * iH);
const g = rgba[1] / (iW * iH);
const b = rgba[2] / (iW * iH);
const a = rgba[3] / (iW * iH);
let resRGBA = [Math.ceil(r), Math.ceil(g), Math.ceil(b), Math.ceil(a)];
RGBをHSVへ変換
色を純粋に判定したい場合はHSVが便利
- H:色相 RGB的な色を判定に利用
- S:彩度 白の判定に利用
- V:明度 黒の判定に利用
function rgb2hsv (rgb) {
var r = rgb[0] / 255;
var g = rgb[1] / 255;
var b = rgb[2] / 255;
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var diff = max - min;
var h = 0;
switch (min) {
case max: h = 0; break;
case r: h = (60 * ((b - g) / diff)) + 180; break;
case g: h = (60 * ((r - b) / diff)) + 300; break;
case b: h = (60 * ((g - r) / diff)) + 60; break;
}
var s = max == 0 ? 0 : diff / max;
var v = max;
return [h, s, v];
}
RGBY,BK,WHに判別
色相0~360、彩度0~1、明度0~1を利用して判別
やんわり力技なので、Sinとか使ってうまいことできないか、模索したが挫折しこの状態へ。。
function checkColor (rgba) {
var ret = "";
var hsvRGBA = U.rgb2hsv(rgba);//色相
var hRGBA = hsvRGBA[0];//色相
var sRGBA = hsvRGBA[1];//彩度0で白
var vRGBA = hsvRGBA[2];//明度0で黒
if (sRGBA < 0.2) {
ret = "White";
} else if (vRGBA < 0.2) {
ret = "Black";
} else if (
(315 < hRGBA && hRGBA <= 360) ||
(0 < hRGBA && hRGBA <= 45)
) {
ret = "Red";
} else if (
(45 < hRGBA && hRGBA <= 135)
) {
ret = "Yellow";
} else if (
(135 < hRGBA && hRGBA <= 200)
) {
ret = "Green";
} else if (
(200 < hRGBA && hRGBA <= 315)
) {
ret = "Blue";
}
return ret;
}
参考サイト
HSV色空間
https://www.peko-step.com/html/hsv.html
RGBをHSVに変換する方法
https://lab.syncer.jp/Web/JavaScript/Snippet/66/