LoginSignup
19
13

More than 3 years have passed since last update.

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

Posted at

はじめに

スクリーンショット 2019-12-04 16.17.55.png
某部活で作業せずにスマブラをする輩がいるので, いつでも部室の様子を見れるようにした話です.
OpenCVとWebSocketで, リアルタイムで様子が見れるものがあっさり作れたので
置いときます.

動作環境

CentOS Linux release 7.5.1804
Python 3.6.8
ロジクール ウェブカメラ C270

実装

以下をインストール

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

ディレクトリ構成

├ main.py
├ templates/
     ├ index.html

サーバー : main.py

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

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

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

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

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

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

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

プログラム全体

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>
    <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

参考

FlaskとWebSocketを使用してリアルタイム通信を行う
OpenCV3をPython3で動かす。画像データ分析入門の為の下準備。

19
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
13