俺はお前が作業していないのを見たぞ

# はじめに
![スクリーンショット 2019-12-04 16.17.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228406/2f963296-d240-df5e-b97a-6eee2d893b8e.png)
某部活で作業せずにスマブラをする輩がいるので, いつでも部室の様子を見れるようにした話です.
OpenCVとWebSocketで, リアルタイムで様子が見れるものがあっさり作れたので
置いときます.

# 動作環境
CentOS Linux release 7.5.1804
Python 3.6.8
[ロジクール ウェブカメラ C270]( https://www.amazon.co.jp/gp/product/B003YUB660/ref=ppx_yo_dt_b_asin_title_o06_s00)

# 実装

以下をインストール

```
pip install opencv-python
pip install flask
pip install gevent
pip install gevent-websocket
```

### ディレクトリ構成

```
├ main.py
├ templates/
     ├ index.html
```


### サーバー : main.py
カメラとの接続は, これでいけます.
引数で繋いでるカメラを指定するみたいです. 1台しか繋いでないなら0で大丈夫なはずです.

```python
# usbbカメラと接続
capture = cv2.VideoCapture(0)
```

カメラからフレームを読み込みます. frameが画像データです.

```python
et, frame = capture.read() # カメラからフレーム読みこみ
```

画像jpgに変換. encimgが画像データです.
90は圧縮率です. 1-100で指定します. 低いほど高圧縮.

```python
# jpgにエンコードするときのパラメーター
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]

result, encimg = cv2.imencode('.jpg', frame, encode_param) #jpgに変換
```

プログラム全体

```python
import cv2
import base64
from flask import Flask, request, render_template
from gevent import pywsgi
from geventwebsocket.handler import WebSocketHandler

app = Flask(__name__)

# usbカメラと接続
capture = cv2.VideoCapture(0)

# jpgにエンコードするときのパラメーター
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/live')
def live():
    if request.environ.get('wsgi.websocket'):
        ws = request.environ['wsgi.websocket']
        while True:
            ret, frame = capture.read() # カメラから画像読みこみ
            result, encimg = cv2.imencode('.jpg', frame, encode_param) #jpgに変換
            ws.send(base64.b64encode(encimg).decode('ascii')) # webbsocketでbase64に変換したjpg画像を送信

　　　
def main():
    app.debug = True
    server = pywsgi.WSGIServer(("", 8080), app, handler_class=WebSocketHandler)
    server.serve_forever()
    
if __name__ == '__main__':
    main()

```

### フロント : index.html
受け取ったら画像を更新するようにするだけです.

```html
<html>
    <head>
        <title>●REC</title>
    </head>
    <body>
        <img id="player" src=""/>
        <script>
            const ws = new WebSocket("wss://localhost/live");
            const player = document.getElementById("player");
            # 受取時の処理
            ws.onmessage = function(e) {
                player.setAttribute("src", "data:image/jpg;base64,"+e.data)
            }
        </script>
    </body>
</html>
```

ここまでできればlocalhost:8080にアクセスすれば画像が表示されるはずです.

### Nginx
nginxのconfです.

```
server{
    listen 80;
    server_name hostname;
    return 301 https://$host$request_uri;
}

server{
    listen 443 ssl;
    client_max_body_size 500M;
    server_name    hostname;

    ssl_certificate         cert.pem;
    ssl_certificate_key     privkey.pem;

    location / {
        proxy_pass    http://localhost:8080/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forward-Proto http;
        proxy_set_header X-Nginx-Proxy true;
        proxy_redirect off;
    }
}
```

# おわりに
対策された、、、
![Image from iOS (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228406/8353eb7f-b539-8a2b-df41-bfb17203458b.jpeg)


# 参考
[FlaskとWebSocketを使用してリアルタイム通信を行う](http://python.zombie-hunting-club.com/entry/2017/11/03/224003)
[OpenCV3をPython3で動かす。画像データ分析入門の為の下準備。](https://qiita.com/Tawasshy/items/1692e4f4b1e84daee45f)