会議室で誰がどこに座っているかわかる「名前調べるくん」をkintoneとobnizとレゴでつくってみた

:::note info
この作品はMaker Faire Tokyo 2021のブース出展用に作成した作品です。
:::

# はじめに

唐突ですが、みなさんこんな経験はないでしょうか?


- はじめましての人が多く参加する会議で、
- 名刺はもらったけど、
- 誰が誰か覚えられず、
- 必死に名刺の位置と着席位置を合わせる!!!

<img src="https://docs.google.com/drawings/d/e/2PACX-1vRa7oBCXDh_zCgi-Z7FHpOF0fFj0ed-4VFBvta_2cyqHA3kfbP2oU5ZW-4KeZBHjCxUijuJQbE9dJpj/pub?w=952&amp;h=464">

<img src="https://docs.google.com/drawings/d/e/2PACX-1vTOcu57qeMh_Lg0wKV5s-voEU2ODoFYytZvlQ0tda2rNzspF3s-dWll1YodWjB_B-RDIRjDjIoqoLz2/pub?w=943&amp;h=462">


焦りますよね・・
特に名字が同じだったり似ていたりするともう無理・・・

ってことでそんな問題を解消？できるような作品を作りました！


# つくったもの

その名も「「**名前調べるくん**」」
レゴでミニチュアな会議室を作りました！

<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/3X3SNrUYVB">pic.twitter.com/3X3SNrUYVB</a></p>&mdash; BB@サブ (@BB_File) <a href="https://twitter.com/BB_File/status/1442831262553493504?ref_src=twsrc%5Etfw">September 28, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

人形の位置を変えると、画面上の名前も変わる！

# 仕組み

obniz Boardにjpegカメラを接続し、HTMLのcanvas上に描画しています。
そして、指定した座標の色を判別させて、kintoneのデータとマッチングさせています。

<img src="https://docs.google.com/drawings/d/e/2PACX-1vSUySebcMua0jxOGhf-tK4XBXqgJq-q6brnUNcPjB6wcRvPjjQ1EMof1C9jmS-IFv86v8drzgMcvizp/pub?w=960&amp;h=720">

:::note warn
当初はMicrosoftのFace APIを使おうとしたのですが、レゴの顔が同じなのか精度が良くなく、色で判別する方法にしました。本当は顔認証が良いんですけどね・・・
:::

# つくったプログラム

obniz Boardのカメラ処理とcanvas処理がメインです。HTML、CSS、JavaScriptで作っています。
もはやkintoneの画面上に埋め込む必要なくない？って話ですが、まぁそこは目を瞑ってください 笑

## obniz Boardでカメラを扱う

公式ドキュメントにサンプルコードが載っていたので全然苦戦せずに実装できました。

> ▶ ArduCAMMini - obniz Parts Library
> https://obniz.com/ja/sdk/parts/ArduCAMMini/README.md

カメラで取得するサイズが大きいとラグも大きくなるので、そこそこサイズの `800×600` にしています。

```javascript
obniz.onconnect = async () => {
  const cam = obniz.wired("ArduCAMMini", {
    cs: 0,
    mosi: 1,
    miso: 2,
    sclk: 3,
    gnd: 4,
    vcc: 5,
    sda: 6,
    scl: 7,
  });
  await cam.startupWait();

  // 定期的にカメラ画像を取得する
  while (true) {
    const data = await cam.takeWait("800x600");
    const base64 = cam.arrayToBase64(data);
```

## 座標の特定

画像のどこの色を判別するかはcanvasのピクセルで指定しています。
ここがアナログなんですよねw（ちょっとカメラの位置がズレたらアウト）

```javascript
// 色識別結果を表示
const upleft = ctx.getImageData(50, 140, 10, 10);
const upright = ctx.getImageData(750, 140, 10, 10);
const downleft = ctx.getImageData(50, 530, 10, 10);
const downright = ctx.getImageData(750, 530, 10, 10);
```

## 色の判別

超アナログかつ実運用には耐えられない色識別ですw
現に光の具合で誤認識しまくりでした（汗）

```javascript
// RGBの値で色を特定する
if (r < 100 && g < 100 && b < 100) {
  color = "black";
}
if (r > 230 && g > 230 && b > 230) {
  color = "white";
}
if (r > 200 && g < 100 && b < 110) {
  color = "red";
}
if (r > 200 && g > 150 && b < 200) {
  color = "yellow";
}
```

何回か試して「だいだいこの範囲ならこの色っしょ」ってことにしてます。


## kintoneとのマッピング

kintoneのレコードデータを元に、判別した色からデータ（≒ 人の情報）を特定させています。
都度データを取得して特定だと無駄が多いので、最初にkintoneのデータをごそっと取得して、
あとはJavaScript上で`Array.find` とか `Array.map` とか使ってやってます。

JavaScript用のSDK **「kintone JavaScript Client」** を使うとファイル操作とかも楽に記述できて便利です！

```JavaScript
import { KintoneRestAPIClient } from "@kintone/rest-api-client";
const client = new KintoneRestAPIClient();

〜〜〜

  const myFunc = {
    getRecords: () => {
      // kintoneのレコードを全件取得する関数
      const app = kintone.app.getId();
      return client.record.getAllRecords({ app });
    },
    getImage: (fileKey) => {
      // kintoneのレコード内の添付ファイルをDLする関数
      return client.file.downloadFile({ fileKey });
    },
    ditectRecord: (ditectColor, records) => {
      // 判定した色からkintoneのレコードを特定する関数
      return records.find((val) => val.color === ditectColor);
    },
    〜〜〜
```


他、全体のコードはGitHubにアップしてます。
https://github.com/RyBB/namae-siraberu-kun

# おわりに

ZoomなどのWeb会議では右下とかに名前が表示されていたりするので楽ですが、今思うとリアル会議って大変でしたね。
新人のころは特に焦っていた記憶がありますw

今回はMaker Faireのイベントブース用なので、レゴを使って少しおもちゃっぽく作りましたが、
会議室のテーブル中央に360°カメラを設置してFace APIを使えば、実際に使えるものができるのではないでしょうか。

それでは！≧(+･` ཀ･´)≦