Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

ブラウザでウェブカメラ映像のタッチのから色をRGBY-BK-WH判別

More than 1 year has passed since last update.

ブラウザでカメラ映像から色を判別するときに利用したチップスをメモ

ウェブカメラ動画の取得

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/

mmt
コーディングするデザイナー目指します、ウェブ技術を活用した試作(PoC)作りが、最近のトレンド。 https://codepen.io/mmt-codepen
hol-on
デザインのご相談なら!ホロンクリエイトにお任せください。産業デザイン(UX・UIデザイン/プロダクトデザイン/WEB・サービスデザイン)に関わるコンセプト構築から製品化まで、様々な分野でのデザイン開発をサポートします。
http://www.hol-on.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away