PC使用時の猫背を矯正するクソアプリ


[クソアプリアドベントカレンダー](https://qiita.com/advent-calendar/2021/kuso-app)に空きがあったので投稿してみようと思いました
Qiita初投稿なので至らぬところなどがあるかもしれませんがよろしくお願いします


### 前置き（呼び飛ばしてもらって構いません）
毎年Qiitaのアドベントカレンダーを楽しませて頂いております、@takuminmin0718です
プログラミングを本格的に学習し始めてから３年間、ほとんど公の場に成果物などを晒すことがありませんでした
でもそろそろチャレンジしてもいいかな、と思って今年の[クソアプリアドベントカレンダー](https://qiita.com/advent-calendar/2021/kuso-app)用にこのアプリを作ってみましたが、作ったはいいものの記事を書く自信はなかったり忙しかったりして、しばらく放置してしまいました


ですが最近になって記事を書く余裕が出てきて、カレンダーにも空きがあったので、チャレンジしてみようと思います

# きっかけ
みなさん、猫背にお悩みではありませんか？
自分は昔から結構猫背がひどいので、最近ちょくちょく試してた機械学習を使って解決出来たらいいなーって思ってこのアプリを作ってみました~~そもそもモニターの位置が低すぎるのが原因な気がする~~

### 現状
僕の場合、長時間座ってると気づいたら猫背になっちゃいます
猫背になった時に教えてほしい

→**パソコン使用時に猫背を検知し、注意を促す**

# 設計

### 材料
 - Ruby RailsやらSinatraもある程度使える
 - 機械学習 TensorFlowを触ったことはある程度の超初心者
 - RaspberryPi 3B+ ちょうど役割が無くて余ってました
 - webカメラ エレコムの猫？の顔がついてるかわいいやつ、古くて画質もよくないし画角も狭い

材料はたったこれだけ

### 想定する動き
webカメラ+ラズパイで物体検出して、猫背を検出何かしらのアクションを起こして使用者に注意を促す

**アクションの候補**

 - 警告ランプ+アラームで警告
 - パソコンを使用不可にする
 
ただ単に電気を光らせて音を出すだけじゃ面白くないかなぁ、って思ったので今回は下の**パソコンを使用不可にする**を採用します

パソコンを使用不可にするために、電源をぶち切るわけにもいかないので画面上のすべてのウィンドウを隠して使用不可にします
具体的には、パソコンでサーバーを立てて、ラズパイからのリクエストがあればウィンドウを隠したり表示しなおしたりします


**まとめると、**
![無題のプレゼンテーション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1250322/8980f609-7353-85fd-de1d-9a691860754b.png)
こうなります
※SinatraはRubyの手軽に使えるサーバーライブラリ、[SendKeys](https://www.vector.co.jp/soft/win95/net/se250664.html)はWindowsのキー入力をコマンドラインから簡単に行えるツール

# 実装
### 物体認識（ラズパイ）
物体認識を扱うのは初めてで右も左もわからない状態だったため、[こちらの解説記事](https://dream-soft.mydns.jp/blog/developper/smarthome/2021/02/2809/)を少しいじって使用させていただきました、ありがとうございます！

この記事の通りアノテーションはIBM Cloud Annotationsで行い、モデルの学習はGoogle Colaboratoryで行いました

画像の訓練データは、机の横から撮った動画から切り出して作成しました↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1250322/1c930a34-d2a8-6c71-f7ed-7e6502a0ef19.png)
（iPhoneで撮った写真なのでwebカメラよりもだいぶきれいです）
この画角で、いろんな服を着て猫背で座ったり背筋を伸ばして座ったり、姿勢がいい人に座ってもらったりして結構な数（1138枚）のデータを得ました

:::note info
アノテーションは想像以上に大変でした、、、でもこれもいい勉強になったかな
モデルの学習もGPU使ったのに結構時間かかりました、ローカル環境（GPUなし、core i3 8100）だったらどうなってたことやら
:::

### サーバー（Windowsパソコン）
Sinatraを使って実装しました、非常に分かりやすいのでめちゃくちゃ単純なアプリを作るときやサーバーを初めて触ってみるときにお勧めですよ!(^^)!

```ruby
require "sinatra"
require "fiddle/import" # fiddleはコマンドを実行するために必要
require "fiddle/types"


def hide_window
  system 'sendkeys/sendkeys.exe "/active" [Win]d'
end


get "/hide_window" do
  hide_window
end
```
※これを実行する前に、SendKeysを[ここ](https://www.vector.co.jp/soft/win95/net/se250664.html)からダウンロード・展開して、同じディレクトリに配置する必要があります

こんなコードになります、めっちゃシンプル
`http://windowsのローカルipアドレス/hide_window`にアクセスしたときに、`get "/hide_window"`あとの`do`と`end`間が実行されます
この場合は、SendKeysに`win+Dを押下する`という命令をコマンドライン経由で送る、`hide_window`メソッドが実行されます

### 設置
訓練データは画角の広いiPhoneで三脚を立てて撮影しましたが、webカメラは画角が狭く背中がしっかり画角に収まらないので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1250322/a8913874-c123-19b1-1d2c-94c430bd79ce.png)
壁にかかってるマグネットボードに貼り付けました

ラズパイはマグネットボードの下にある勉強机の端に設置しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1250322/5da40854-0f9c-93e4-6d0c-faa9983c74d1.png)

# 完成！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1250322/c2937233-a6e3-ce16-1752-c9f47c681334.png)
きちんと正しい姿勢を認識していますね

実際に使ってみた
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">猫背を検知してウィンドウを勝手に隠すアプリ作りました <a href="https://t.co/hn0STei2Po">pic.twitter.com/hn0STei2Po</a></p>&mdash; taku minmin (@takuminmin0718) <a href="https://twitter.com/takuminmin0718/status/1473253589112201216?ref_src=twsrc%5Etfw">December 21, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# おわりに
ということで今回は、**PC使用時の猫背を矯正するクソアプリ**を作ってみました
ファーストインプレッションとしては、**「意外とちゃんと認識するし、猫背になった時に気づけて効果的！」**という感じでした！~~数回しか使ってないけど~~

突飛なアイデアでしたが案外うまく動いたので嬉しかったです
この経験を今後も活かせるように頑張ります

**最後まで読んでいただきありがとうございました！**