billiard/app.py

194 lines
6.5 KiB
Python
Raw Normal View History

2023-08-06 05:43:37 +00:00
import cv2
import json
import time
import requests
2023-09-22 05:59:08 +00:00
import threading
2023-09-22 03:33:22 +00:00
import numpy as np
2023-08-06 05:43:37 +00:00
import supervision as sv
2023-09-21 12:15:54 +00:00
from datetime import datetime
2023-08-06 05:43:37 +00:00
from ultralytics import YOLO
from flask import Flask,request,Response
from multiprocessing import Process, Event
app = Flask(__name__)
workers = {}
@app.route('/start/<id>')
def start(id):
table = workers.get(id)
if table is not None:
table.set()
source = request.args.get('source')
target = request.args.get('target')
region = request.args.get('region')
if target is None:
return "please input target url"
return Response(worker(id,source,region,True), mimetype='text/event-stream')
stop_event = Event()
p = Process(target=workerloop, args=(stop_event,id,source,target,region))
p.start()
workers[id] = stop_event
return 'ok'
@app.route('/stop/<id>')
def stop(id):
table = workers.get(id)
if table is not None:
table.set()
return 'ok'
@app.route('/show',methods=['POST'])
def show():
2023-09-21 12:15:54 +00:00
# print(request.json)
data = request.json["content"]
2023-09-22 04:01:37 +00:00
info(data)
return 'ok'
def info(data):
2023-09-21 12:15:54 +00:00
balls = data["balls"]
table = data["table"]
text = f"table:{table:>3} "
for i in range(16):
ball = "#" if "ball"+str(i) in balls else " "
text += f"| {i} : {ball} "
print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'),text)
2023-08-06 05:43:37 +00:00
def worker(id,source,region=None,stream=False):
if region == None:
2023-08-14 08:59:16 +00:00
region = 10
2023-08-06 05:43:37 +00:00
else:
region = int(region)
2023-09-22 07:25:34 +00:00
print("start loading model...",id,source,region)
2023-08-06 05:43:37 +00:00
model = YOLO('./best.pt')
2023-09-22 07:25:34 +00:00
print("start loaded model!!!")
2023-08-06 05:43:37 +00:00
balls = {}
2023-08-14 08:59:16 +00:00
count = 0
2023-08-06 05:43:37 +00:00
try:
cap = cv2.VideoCapture(source)
if not cap.isOpened():
2023-09-21 13:40:47 +00:00
print("Error opening video stream.")
2023-08-06 05:43:37 +00:00
while True:
2023-09-22 05:59:08 +00:00
use = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
bgn = (time.time()*1000)
2023-08-06 05:43:37 +00:00
ret, frame = cap.read()
2023-09-22 06:08:22 +00:00
del(ret)
del(frame)
ret, frame = cap.read()
2023-09-22 05:59:08 +00:00
use += " read:"+str((time.time()*1000) - bgn)
2023-08-06 05:43:37 +00:00
if not ret:
print("Error read video stream.")
2023-09-21 13:20:07 +00:00
cap = cv2.VideoCapture(source)
if not cap.isOpened():
2023-09-21 13:40:47 +00:00
print("Error opening video stream..")
cap = cv2.VideoCapture(source)
2023-09-22 03:27:05 +00:00
time.sleep(1)
2023-09-21 13:40:47 +00:00
if not cap.isOpened():
print("Error opening video stream...")
2023-09-22 03:27:05 +00:00
time.sleep(3)
if not cap.isOpened():
print("Error opening video stream....")
2023-09-21 13:40:47 +00:00
break
2023-09-21 13:20:07 +00:00
continue
2023-09-21 12:38:58 +00:00
result = model.track(frame,show=False,stream=False,persist=True,device=int(id)%4)
2023-09-22 05:59:08 +00:00
use += " track:"+str((time.time()*1000) - bgn)
2023-09-22 04:30:27 +00:00
del(ret)
del(frame)
2023-08-06 05:43:37 +00:00
result = result[0]
detections = sv.Detections.from_yolov8(result)
2023-09-21 13:50:38 +00:00
if result.boxes.id is not None:
detections.tracker_id = result.boxes.id.cpu().numpy().astype(int)
2023-09-22 03:27:05 +00:00
else:
detections.tracker_id = np.array([])
detections.conf = np.array([])
detections.xyxy=np.empty((0, 4), dtype=np.float32)
# detections = detections[(detections.tracker_id != None)]
2023-08-14 08:59:16 +00:00
count += 1
2023-08-17 04:19:13 +00:00
names = {}
2023-08-06 05:43:37 +00:00
for xyxy,_, confidence, class_id, tracker_id in detections:
2023-08-17 04:19:13 +00:00
name = model.model.names[class_id]
if name in names:
print("Name duplicate",name)
2023-08-17 05:08:17 +00:00
continue
2023-08-17 04:19:13 +00:00
ball = balls.get(name,{})
2023-08-14 08:59:16 +00:00
ball["tkid"] = int(tracker_id)
ball["conf"] = round(float(confidence), 2)
ball["xyxy"] = [int(xyxy[0]), int(xyxy[1]), int(xyxy[2]), int(xyxy[3])]
ball["count"] = ball.get("count",0) + 1
if region - count < 3:
ball["final"] = ball.get("final",0) + 1
2023-08-17 04:19:13 +00:00
balls[name] = ball
names[name] = True
2023-08-17 05:08:17 +00:00
names = {}
2023-09-22 05:59:08 +00:00
use += " names:"+str((time.time()*1000) - bgn)
2023-08-14 08:59:16 +00:00
if count < region:
2023-08-06 05:43:37 +00:00
continue
2023-09-22 04:01:37 +00:00
data = {"table":id,"balls":balls,"time":int(time.time()*1000)}
info(data)
json_data = json.dumps(data)
2023-08-06 05:43:37 +00:00
balls = {}
2023-08-14 08:59:16 +00:00
count = 0
2023-09-22 05:59:08 +00:00
use += " dump:"+str((time.time()*1000) - bgn)
2023-08-06 05:43:37 +00:00
if not stream:
yield json_data
else:
yield f"data: {json_data}\n\n"
2023-09-22 05:59:08 +00:00
use += " yield:"+str((time.time()*1000) - bgn)
2023-09-22 07:55:28 +00:00
print("model.track",use)
2023-08-06 05:43:37 +00:00
except GeneratorExit:
print("Client disconnected at", time.ctime())
finally:cap.release()
def workerloop(stop_event,id,source,target=None,region=None):
try:
gen = worker(id,source,region)
for data in gen:
2023-09-22 05:59:08 +00:00
use = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
bgn = (time.time()*1000)
2023-08-06 05:43:37 +00:00
if stop_event.is_set():
break
json_data = json.loads(data)
2023-09-22 05:59:08 +00:00
use += " loads:"+str((time.time()*1000) - bgn)
2023-08-06 05:43:37 +00:00
text = json.dumps({"content":json_data})
2023-09-22 05:59:08 +00:00
use += " dumps:"+str((time.time()*1000) - bgn)
2023-08-06 05:43:37 +00:00
2023-09-22 05:59:08 +00:00
# 创建并启动线程
thread = threading.Thread(target=post_request, args=(target, text))
thread.start()
use += " post:"+str((time.time()*1000) - bgn)
2023-09-22 07:55:28 +00:00
print("workerloop",use)
2023-08-06 05:43:37 +00:00
finally:
gen.close()
2023-09-22 05:59:08 +00:00
def post_request(url, data):
2023-09-22 07:55:28 +00:00
use = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
bgn = (time.time()*1000)
2023-09-22 05:59:08 +00:00
headers = {
"Content-Type": "application/json"
}
response = requests.post(url, data=data,headers=headers)
2023-09-22 11:58:24 +00:00
use += " post:"+str((time.time()*1000) - bgn ) +"ms"
2023-09-22 11:51:49 +00:00
print("post_request",use,response.text)
2023-08-06 05:43:37 +00:00
2023-09-22 07:22:23 +00:00
# import pstats
# import cProfile
# def test_function():
# url = "rtmp://rtmp03open.ys7.com:1935/v3/openlive/L05874022_1_1?expire=1726389273&id=625006970167889920&t=2c7f371063e4ad672cb7a7c34b2a236e9ff37b02052f818c9c4fe7ae9632cd0e&ev=100"
# gen = worker(0,url,5)
# count = 0
# for data in gen:
# count += 1
# if count > 10:
# break
2023-08-06 05:43:37 +00:00
if __name__ == '__main__':
2023-09-22 07:22:23 +00:00
# cProfile.run('test_function()', 'test_function.profile')
# p = pstats.Stats('test_function.profile')
# p.sort_stats('cumulative').print_stats(100) # Top 10 by cumulative time
2023-08-06 05:43:37 +00:00
app.run("0.0.0.0",threaded=True)