-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
118 lines (85 loc) · 3.03 KB
/
app.py
File metadata and controls
118 lines (85 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import cv2
import supervision
import asyncio
import threading
import logging
from functools import partial
from inference.core.interfaces.camera.entities import VideoFrame
from flask import Flask, render_template, request
from computer_vision import infer
from flask_socketio import SocketIO
from flask_cors import CORS
from game import run_game, account_player_action
from db import db
app = Flask(__name__)
CORS(app)
socket = SocketIO(app, cors_allowed_origins="*")
label_annotator = supervision.LabelAnnotator()
box_annotator = supervision.BoundingBoxAnnotator()
logger = logging.getLogger(__name__)
db().save("is_playing", False)
@app.route("/play", methods=["POST"])
def play():
room_key = request.form.get("room_key")
db().save("is_playing", True)
run_game(socket, room_key)
db().save("is_playing", False)
return {"message": "Game started"}
@app.route("/")
def index():
return render_template("index.html")
@app.route("/room/<room_key>")
def room(room_key):
# gets player name from query string
player_name = request.args.get("name")
if not player_name:
return "Player name is required", 400
# Start the inference in a background thread
inference_thread = threading.Thread(
target=partial(start_inference, room_key, player_name)
)
inference_thread.daemon = True
inference_thread.start()
return render_template("room.html", room_key=room_key, player_name=player_name)
async def async_inference(room_key, player_name):
await asyncio.to_thread(
infer,
"rock-paper-scissors-sxsw/11",
0,
on_prediction=partial(
process_predictions, room_key=room_key, player_name=player_name
),
)
def start_inference(room_key, player_name):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(async_inference(room_key, player_name))
def publish_buffered_frame_to_socket(room_key, player_name, frame):
_, buffer = cv2.imencode(".jpg", frame)
frame = buffer.tobytes()
socket.emit("debug", "emitting frame")
socket.emit("frame", frame)
def annotated_frame(predictions: dict, video_frame: VideoFrame):
labels = [p["class"] for p in predictions["predictions"]]
detections = supervision.Detections.from_inference(predictions)
annotated = box_annotator.annotate(
scene=video_frame.image.copy(), detections=detections
)
annotated = label_annotator.annotate(
scene=annotated, labels=labels, detections=detections
)
return annotated
def process_predictions(
predictions: dict,
video_frame: VideoFrame,
room_key: str = None,
player_name: str = None,
):
if db().get("is_playing"):
frame_to_render = annotated_frame(predictions, video_frame)
account_player_action(socket, room_key, player_name, predictions)
else:
frame_to_render = video_frame.image
publish_buffered_frame_to_socket(room_key, player_name, frame_to_render)
if __name__ == "__main__":
socket.run(app, debug=True, host="0.0.0.0", port=8080)