mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 19:26:31 +00:00
fixed inference bugs
add DONE during inference, correct handling on C# side
This commit is contained in:
+1
-1
@@ -50,7 +50,7 @@ This is crucial for the build because build needs Python.h header and other file
|
||||
pip install ultralytics
|
||||
|
||||
pip uninstall -y opencv-python
|
||||
pip install opencv-python cython msgpack cryptography rstream pika zmq pyjwt
|
||||
pip install opencv-python cython msgpack cryptography rstream pika zmq pyjwt pyinstaller tensorboard
|
||||
```
|
||||
In case of fbgemm.dll error (Windows specific):
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
pyinstaller --onefile ^
|
||||
--collect-all jwt ^
|
||||
--collect-all requests ^
|
||||
--collect-all psutil ^
|
||||
--collect-all cryptography ^
|
||||
--collect-all msgpack ^
|
||||
--collect-all expecttest ^
|
||||
--collect-all torch ^
|
||||
--collect-all ultralytics ^
|
||||
--collect-all zmq ^
|
||||
--hidden-import user ^
|
||||
--hidden-import security ^
|
||||
--hidden-import secure_model ^
|
||||
--hidden-import api_client ^
|
||||
--hidden-import hardware_service ^
|
||||
--hidden-import constants ^
|
||||
--hidden-import annotation ^
|
||||
--hidden-import remote_command ^
|
||||
--hidden-import ai_config ^
|
||||
--hidden-import inference ^
|
||||
--hidden-import remote_command_handler ^
|
||||
start.py
|
||||
@@ -1,17 +0,0 @@
|
||||
import main
|
||||
from main import ParsedArguments
|
||||
|
||||
|
||||
def start_server():
|
||||
args = ParsedArguments('admin@azaion.com', 'Az@1on1000Odm$n', 'stage', True)
|
||||
processor = main.CommandProcessor(args)
|
||||
try:
|
||||
processor.start()
|
||||
except Exception as e:
|
||||
processor.stop()
|
||||
|
||||
def on_annotation(self, cmd, annotation):
|
||||
print('on_annotation hit!')
|
||||
|
||||
if __name__ == "__main__":
|
||||
start_server()
|
||||
@@ -7,11 +7,13 @@ cdef class Inference:
|
||||
cdef object on_annotation
|
||||
cdef Annotation _previous_annotation
|
||||
cdef AIRecognitionConfig ai_config
|
||||
cdef bint stop_signal
|
||||
|
||||
cdef bint is_video(self, str filepath)
|
||||
cdef run_inference(self, RemoteCommand cmd, int batch_size=?)
|
||||
cdef _process_video(self, RemoteCommand cmd, int batch_size)
|
||||
cdef _process_image(self, RemoteCommand cmd)
|
||||
cdef stop(self)
|
||||
|
||||
cdef frame_to_annotation(self, long time, frame, boxes: object)
|
||||
cdef bint is_valid_annotation(self, Annotation annotation)
|
||||
|
||||
+12
-7
@@ -1,5 +1,3 @@
|
||||
import ai_config
|
||||
import msgpack
|
||||
from ultralytics import YOLO
|
||||
import mimetypes
|
||||
import cv2
|
||||
@@ -13,6 +11,7 @@ cdef class Inference:
|
||||
def __init__(self, model_bytes, on_annotation):
|
||||
loader = SecureModelLoader()
|
||||
model_path = loader.load_model(model_bytes)
|
||||
self.stop_signal = False
|
||||
self.model = YOLO(<str>model_path)
|
||||
self.on_annotation = on_annotation
|
||||
|
||||
@@ -22,19 +21,20 @@ cdef class Inference:
|
||||
|
||||
cdef run_inference(self, RemoteCommand cmd, int batch_size=8):
|
||||
print('run inference..')
|
||||
|
||||
self.stop_signal = False
|
||||
if self.is_video(cmd.filename):
|
||||
return self._process_video(cmd, batch_size)
|
||||
self._process_video(cmd, batch_size)
|
||||
else:
|
||||
return self._process_image(cmd)
|
||||
self._process_image(cmd)
|
||||
|
||||
cdef _process_video(self, RemoteCommand cmd, int batch_size):
|
||||
frame_count = 0
|
||||
batch_frame = []
|
||||
self._previous_annotation = None
|
||||
v_input = cv2.VideoCapture(<str>cmd.filename)
|
||||
self.ai_config = AIRecognitionConfig.from_msgpack(cmd.data)
|
||||
|
||||
while v_input.isOpened():
|
||||
while v_input.isOpened() and not self.stop_signal:
|
||||
ret, frame = v_input.read()
|
||||
ms = v_input.get(cv2.CAP_PROP_POS_MSEC)
|
||||
if not ret or frame is None:
|
||||
@@ -51,7 +51,9 @@ cdef class Inference:
|
||||
for frame, res in zip(batch_frame, results):
|
||||
annotation = self.frame_to_annotation(int(frame[1]), frame[0], res.boxes)
|
||||
|
||||
if self.is_valid_annotation(<Annotation>annotation):
|
||||
is_valid = self.is_valid_annotation(<Annotation>annotation)
|
||||
print(f'Is valid annotation: {is_valid}')
|
||||
if is_valid:
|
||||
self._previous_annotation = annotation
|
||||
self.on_annotation(cmd, annotation)
|
||||
batch_frame.clear()
|
||||
@@ -64,6 +66,9 @@ cdef class Inference:
|
||||
annotation = self.frame_to_annotation(0, frame, res[0].boxes)
|
||||
self.on_annotation(cmd, annotation)
|
||||
|
||||
cdef stop(self):
|
||||
self.stop_signal = True
|
||||
|
||||
cdef frame_to_annotation(self, long time, frame, boxes: Boxes):
|
||||
detections = []
|
||||
for box in boxes:
|
||||
|
||||
+16
-34
@@ -1,6 +1,7 @@
|
||||
import traceback
|
||||
from queue import Queue
|
||||
cimport constants
|
||||
import msgpack
|
||||
|
||||
from api_client cimport ApiClient
|
||||
from annotation cimport Annotation
|
||||
@@ -8,23 +9,21 @@ from inference cimport Inference
|
||||
from remote_command cimport RemoteCommand, CommandType
|
||||
from remote_command_handler cimport RemoteCommandHandler
|
||||
from user cimport User
|
||||
import argparse
|
||||
|
||||
cdef class ParsedArguments:
|
||||
cdef str email, password, folder;
|
||||
cdef bint persist_token
|
||||
|
||||
def __init__(self, str email, str password, str folder, bint persist_token):
|
||||
def __init__(self, str email, str password, str folder):
|
||||
self.email = email
|
||||
self.password = password
|
||||
self.folder = folder
|
||||
self.persist_token = persist_token
|
||||
|
||||
cdef class CommandProcessor:
|
||||
cdef ApiClient api_client
|
||||
cdef RemoteCommandHandler remote_handler
|
||||
cdef object command_queue
|
||||
cdef bint running
|
||||
cdef Inference inference
|
||||
|
||||
def __init__(self, args: ParsedArguments):
|
||||
self.api_client = ApiClient(args.email, args.password, args.folder)
|
||||
@@ -32,25 +31,31 @@ cdef class CommandProcessor:
|
||||
self.command_queue = Queue(maxsize=constants.QUEUE_MAXSIZE)
|
||||
self.remote_handler.start()
|
||||
self.running = True
|
||||
model = self.api_client.load_ai_model()
|
||||
self.inference = Inference(model, self.on_annotation)
|
||||
|
||||
def start(self):
|
||||
while self.running:
|
||||
try:
|
||||
command = self.command_queue.get()
|
||||
model = self.api_client.load_ai_model()
|
||||
Inference(model, self.on_annotation).run_inference(command)
|
||||
self.inference.run_inference(command)
|
||||
self.remote_handler.send(command.client_id, <bytes>'DONE'.encode('utf-8'))
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
|
||||
cdef on_command(self, RemoteCommand command):
|
||||
try:
|
||||
if command.command_type == CommandType.INFERENCE:
|
||||
self.command_queue.put(command)
|
||||
if command.command_type == CommandType.GET_USER:
|
||||
self.get_user(command, self.api_client.get_user())
|
||||
elif command.command_type == CommandType.LOAD:
|
||||
response = self.api_client.load_bytes(command.filename)
|
||||
self.remote_handler.send(command.client_id, response)
|
||||
elif command.command_type == CommandType.GET_USER:
|
||||
self.get_user(command, self.api_client.get_user())
|
||||
elif command.command_type == CommandType.INFERENCE:
|
||||
self.command_queue.put(command)
|
||||
elif command.command_type == CommandType.STOP_INFERENCE:
|
||||
self.inference.stop()
|
||||
elif command.command_type == CommandType.EXIT:
|
||||
self.stop()
|
||||
else:
|
||||
pass
|
||||
except Exception as e:
|
||||
@@ -64,28 +69,5 @@ cdef class CommandProcessor:
|
||||
self.remote_handler.send(cmd.client_id, data)
|
||||
|
||||
def stop(self):
|
||||
self.remote_handler.stop()
|
||||
self.running = False
|
||||
|
||||
def parse_arguments():
|
||||
parser = argparse.ArgumentParser(description="Command Processor")
|
||||
parser.add_argument("-e", "--email", type=str, default="", help="Email")
|
||||
parser.add_argument("-p", "--pw", type=str, default="", help="Password")
|
||||
parser.add_argument("-f", "--folder", type=str, default="", help="Folder to API inner folder to download file from")
|
||||
parser.add_argument("-t", "--persist_token", type=bool, default=True, help="True for persisting token from API")
|
||||
cdef args = parser.parse_args()
|
||||
|
||||
cdef str email = args.email
|
||||
cdef str password = args.pw
|
||||
cdef str folder = args.folder
|
||||
cdef bint persist_token = args.persist_token
|
||||
|
||||
return ParsedArguments(email, password, folder, persist_token)
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parse_arguments()
|
||||
processor = CommandProcessor(args)
|
||||
try:
|
||||
processor.start()
|
||||
except KeyboardInterrupt:
|
||||
processor.stop()
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
cdef enum CommandType:
|
||||
INFERENCE = 1
|
||||
LOAD = 2
|
||||
GET_USER = 3
|
||||
GET_USER = 10
|
||||
LOAD = 20
|
||||
INFERENCE = 30
|
||||
STOP_INFERENCE = 40
|
||||
EXIT = 100
|
||||
|
||||
cdef class RemoteCommand:
|
||||
cdef public bytes client_id
|
||||
|
||||
@@ -8,9 +8,11 @@ cdef class RemoteCommand:
|
||||
|
||||
def __str__(self):
|
||||
command_type_names = {
|
||||
1: "INFERENCE",
|
||||
2: "LOAD",
|
||||
3: "GET_USER"
|
||||
10: "GET_USER",
|
||||
20: "LOAD",
|
||||
30: "INFERENCE",
|
||||
40: "STOP INFERENCE",
|
||||
100: "EXIT"
|
||||
}
|
||||
data_str = f'. Data: {len(self.data)} bytes' if self.data else ''
|
||||
return f'{command_type_names[self.command_type]}: {self.filename}{data_str}'
|
||||
|
||||
@@ -12,4 +12,4 @@ cdef class RemoteCommandHandler:
|
||||
cdef _proxy_loop(self)
|
||||
cdef _worker_loop(self)
|
||||
cdef send(self, bytes client_id, bytes data)
|
||||
cdef close(self)
|
||||
cdef stop(self)
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import time
|
||||
import zmq
|
||||
from threading import Thread, Event
|
||||
from remote_command cimport RemoteCommand
|
||||
cimport constants
|
||||
|
||||
|
||||
cdef class RemoteCommandHandler:
|
||||
def __init__(self, object on_command):
|
||||
self._on_command = on_command
|
||||
@@ -59,8 +61,9 @@ cdef class RemoteCommandHandler:
|
||||
socket.send_multipart([client_id, data])
|
||||
print(f'{len(data)} bytes was sent to client {client_id}')
|
||||
|
||||
cdef close(self):
|
||||
cdef stop(self):
|
||||
self._shutdown_event.set()
|
||||
time.sleep(0.5)
|
||||
self._router.close()
|
||||
self._dealer.close()
|
||||
self._context.term()
|
||||
@@ -0,0 +1,22 @@
|
||||
import argparse
|
||||
from main import ParsedArguments, CommandProcessor
|
||||
|
||||
|
||||
def parse_arguments():
|
||||
parser = argparse.ArgumentParser(description="Command Processor")
|
||||
parser.add_argument("-e", "--email", type=str, default="", help="Email")
|
||||
parser.add_argument("-p", "--pw", type=str, default="", help="Password")
|
||||
parser.add_argument("-f", "--folder", type=str, default="", help="Folder to API inner folder to download file from")
|
||||
args = parser.parse_args()
|
||||
|
||||
return ParsedArguments(args.email, args.pw, args.folder)
|
||||
|
||||
def start(args: ParsedArguments):
|
||||
processor = CommandProcessor(args)
|
||||
try:
|
||||
processor.start()
|
||||
except KeyboardInterrupt:
|
||||
processor.stop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
start(parse_arguments())
|
||||
+1
-1
@@ -1 +1 @@
|
||||
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiJkOTBhMzZjYS1lMjM3LTRmYmQtOWM3Yy0xMjcwNDBhYzg1NTYiLCJ1bmlxdWVfbmFtZSI6ImFkbWluQGF6YWlvbi5jb20iLCJyb2xlIjoiQXBpQWRtaW4iLCJuYmYiOjE3MzgxNjM2MzYsImV4cCI6MTczODE3ODAzNiwiaWF0IjoxNzM4MTYzNjM2LCJpc3MiOiJBemFpb25BcGkiLCJhdWQiOiJBbm5vdGF0b3JzL09yYW5nZVBpL0FkbWlucyJ9.7VVws5mwGqx--sGopOuZE9iu3dzt1UdVPXeje2KZTYk
|
||||
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiJkOTBhMzZjYS1lMjM3LTRmYmQtOWM3Yy0xMjcwNDBhYzg1NTYiLCJ1bmlxdWVfbmFtZSI6ImFkbWluQGF6YWlvbi5jb20iLCJyb2xlIjoiQXBpQWRtaW4iLCJuYmYiOjE3MzgzNjUwMjksImV4cCI6MTczODM3OTQyOSwiaWF0IjoxNzM4MzY1MDI5LCJpc3MiOiJBemFpb25BcGkiLCJhdWQiOiJBbm5vdGF0b3JzL09yYW5nZVBpL0FkbWlucyJ9.5teWb-gnhRngV337u_0OyUQ-o2-plN7shrvvKUsckPw
|
||||
Reference in New Issue
Block a user