stuff
This commit is contained in:
Binary file not shown.
@@ -1,255 +0,0 @@
|
|||||||
import numpy as np
|
|
||||||
from functools import partial
|
|
||||||
from hailo_platform import VDevice, HailoSchedulingAlgorithm, FormatType
|
|
||||||
import cv2
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
|
|
||||||
def resize_image(img_in, reshape_to_final=True):
|
|
||||||
if not isinstance(img_in, np.ndarray):
|
|
||||||
img_in = np.asarray(img_in)
|
|
||||||
max_l = 640
|
|
||||||
|
|
||||||
asp_rat = img_in.shape[0] / img_in.shape[1]
|
|
||||||
if asp_rat < 1:
|
|
||||||
output_size = [int(asp_rat * max_l), max_l]
|
|
||||||
else:
|
|
||||||
output_size = [max_l, int(max_l / asp_rat)]
|
|
||||||
|
|
||||||
im_arr_not_pad = cv2.resize(img_in, output_size[::-1])
|
|
||||||
pad_amt = [max_l, max_l] - np.asarray(im_arr_not_pad.shape[0:2])
|
|
||||||
|
|
||||||
left_pad, top_pad = (pad_amt / 2).astype(np.int64)
|
|
||||||
right_pad, bottom_pad = pad_amt - [left_pad, top_pad]
|
|
||||||
|
|
||||||
im_pass = np.zeros(shape=(max_l, max_l, 3), dtype=np.uint8)
|
|
||||||
im_pass[left_pad:(max_l - right_pad),
|
|
||||||
top_pad:(max_l - bottom_pad)] = (im_arr_not_pad)
|
|
||||||
data = im_pass
|
|
||||||
if reshape_to_final:
|
|
||||||
data = np.moveaxis(data, [2], [0])[None, :, :, :]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def model_scoring_callback(completion_info, bindings, data):
|
|
||||||
if completion_info.exception:
|
|
||||||
# handle exception
|
|
||||||
pass
|
|
||||||
ff = bindings.output().get_buffer()
|
|
||||||
|
|
||||||
|
|
||||||
timeout_ms = 1000
|
|
||||||
|
|
||||||
params = VDevice.create_params()
|
|
||||||
params.scheduling_algorithm = HailoSchedulingAlgorithm.ROUND_ROBIN
|
|
||||||
import time
|
|
||||||
|
|
||||||
# The vdevice is used as a context manager ("with" statement) to ensure it's released on time.
|
|
||||||
with VDevice(params) as vdevice:
|
|
||||||
# Create an infer model from an HEF:
|
|
||||||
infer_model = vdevice.create_infer_model("yolov11l_inat.hef")
|
|
||||||
|
|
||||||
# Configure the infer model and create bindings for it
|
|
||||||
with infer_model.configure() as configured_infer_model:
|
|
||||||
bindings = configured_infer_model.create_bindings()
|
|
||||||
st = time.time()
|
|
||||||
for i in range(1):
|
|
||||||
# Set input and output buffers
|
|
||||||
buffer = inp # np.zeros(infer_model.input().shape).astype(np.uint8)
|
|
||||||
bindings.input().set_buffer(buffer)
|
|
||||||
|
|
||||||
output_array = np.zeros([infer_model.output().shape[0]
|
|
||||||
]).astype(np.float32)
|
|
||||||
bindings.output().set_buffer(output_array)
|
|
||||||
|
|
||||||
# Run synchronous inference and access the output buffers
|
|
||||||
configured_infer_model.run([bindings], timeout_ms)
|
|
||||||
buffer = bindings.output().get_buffer()
|
|
||||||
|
|
||||||
# Run asynchronous inference
|
|
||||||
job = configured_infer_model.run_async(
|
|
||||||
[bindings],
|
|
||||||
partial(example_callback, bindings=bindings, data=time.time()),
|
|
||||||
)
|
|
||||||
job.wait(timeout_ms)
|
|
||||||
|
|
||||||
# %%
|
|
||||||
import cv2
|
|
||||||
import time
|
|
||||||
import multiprocessing
|
|
||||||
import numpy as np
|
|
||||||
import ctypes
|
|
||||||
import shutil
|
|
||||||
from utils import *
|
|
||||||
|
|
||||||
cameras = {
|
|
||||||
"camera_sidefeeder": {
|
|
||||||
'url': "rtsp://admin:marybear@192.168.1.157:554/h264Preview_01_sub",
|
|
||||||
'resolution': (480, 640, 3)
|
|
||||||
},
|
|
||||||
"camera_driveway": {
|
|
||||||
'url': "rtsp://admin:marybear@192.168.1.152:554/h264Preview_01_sub",
|
|
||||||
'resolution': (480, 640, 3)
|
|
||||||
},
|
|
||||||
"camera_railing": {
|
|
||||||
'url': "rtsp://admin:marybear@192.168.1.153:554/h264Preview_01_sub",
|
|
||||||
'resolution': (512, 896, 3)
|
|
||||||
},
|
|
||||||
"camera_ptz_right": {
|
|
||||||
'url': "rtsp://admin:marybear@192.168.1.155:554/h264Preview_01_sub",
|
|
||||||
'resolution': (360, 640, 3)
|
|
||||||
},
|
|
||||||
"camera_wrenwatch": {
|
|
||||||
'url': "rtsp://admin:marybear@192.168.1.158:554/h264Preview_01_sub",
|
|
||||||
'resolution': (360, 640, 3)
|
|
||||||
},
|
|
||||||
"camera_backyard": {
|
|
||||||
'url': "rtsp://admin:marybear@192.168.1.162:554/h264Preview_01_sub",
|
|
||||||
'resolution': (432, 1536, 3),
|
|
||||||
'split_into_two': True
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from functools import partial
|
|
||||||
|
|
||||||
cameras = dict()
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
rtsp_url = details['url']
|
|
||||||
resolution = details['resolution']
|
|
||||||
cameras[cam_name] = StreamManager( rtsp_url, resolution, cam_name)
|
|
||||||
|
|
||||||
|
|
||||||
# %%
|
|
||||||
details['cam_name'] = cam_name
|
|
||||||
details['img_array'] = multiprocessing.Array(ctypes.c_uint8,
|
|
||||||
int(array_len),
|
|
||||||
lock=True)
|
|
||||||
details['img_timestamp'] = multiprocessing.Value(ctypes.c_double)
|
|
||||||
details['queue'] = multiprocessing.Queue()
|
|
||||||
details['rtsp_url'] = format_ffmpeg_decode_url(details['url']).split(" ")
|
|
||||||
details['process_func'] = partial(stream_wrapper,
|
|
||||||
details['resolution'],
|
|
||||||
details['rtsp_url'],
|
|
||||||
camera_name=cam_name,
|
|
||||||
queue=details['queue'],
|
|
||||||
img_array=details['img_array'],
|
|
||||||
img_timestamp=details['img_timestamp'])
|
|
||||||
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
p = multiprocessing.Process(target = details['process_func'])
|
|
||||||
details['process'] = p
|
|
||||||
p.start()
|
|
||||||
|
|
||||||
# %%
|
|
||||||
img_array = details['img_array']
|
|
||||||
img_timestamp = details['img_timestamp']
|
|
||||||
|
|
||||||
import time
|
|
||||||
with img_timestamp.get_lock():
|
|
||||||
img_timestamp.value = -1
|
|
||||||
details['queue'].put('get')
|
|
||||||
for i in range(1000):
|
|
||||||
val = img_timestamp.value
|
|
||||||
print(val)
|
|
||||||
if val > 0:
|
|
||||||
|
|
||||||
print('Done')
|
|
||||||
break
|
|
||||||
time.sleep(0.001)
|
|
||||||
|
|
||||||
|
|
||||||
# %%
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
details['queue'].put('get')
|
|
||||||
img_array = details['img_array']
|
|
||||||
img_timestamp = details['img_timestamp']
|
|
||||||
with img_array.get_lock(), img_timestamp.get_lock():
|
|
||||||
reshaped_image = np.frombuffer(details['img_array'].get_obj(),
|
|
||||||
dtype=np.uint8).reshape(
|
|
||||||
details['resolution'])
|
|
||||||
timestamp = img_timestamp.value
|
|
||||||
img_timestamp.value = -1
|
|
||||||
print('Writing for ' + cam_name + f' for {reshaped_image.shape}')
|
|
||||||
cv2.imwrite('images/'+ cam_name + '.jpg', reshaped_image)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# %%
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
img_scoring_queue = multiprocessing.Queue()
|
|
||||||
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
p = multiprocessing.Process(target=rtsp_stream_manager,
|
|
||||||
args=(cam_name, details['gst_pipeline_str'],
|
|
||||||
details['queue'], details['img_array'],
|
|
||||||
details['img_timestamp']))
|
|
||||||
details['process'] = p
|
|
||||||
|
|
||||||
asyncio.create_task(details['async_task'])
|
|
||||||
|
|
||||||
shape = (512, 896, 3)
|
|
||||||
|
|
||||||
asyncio.run(read_stream(shape, cmd))
|
|
||||||
|
|
||||||
import datetime as dt
|
|
||||||
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
details['process'].start()
|
|
||||||
# %%
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
details['queue'].put('restart')
|
|
||||||
# %%
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
details['queue'].put('get')
|
|
||||||
|
|
||||||
if os.path.exists('images/'):
|
|
||||||
shutil.rmtree('images/')
|
|
||||||
|
|
||||||
os.makedirs('images/')
|
|
||||||
|
|
||||||
|
|
||||||
def create_score_message(details, reshaped_image, timestamp):
|
|
||||||
frames = list()
|
|
||||||
|
|
||||||
msg = list()
|
|
||||||
if details.get('split_into_two', False):
|
|
||||||
split_point = int(reshaped_image.shape[1] / 2)
|
|
||||||
left_frame = resize_image(reshaped_image[:, :split_point, :],
|
|
||||||
reshape_to_final=False)
|
|
||||||
right_frame = resize_image(reshaped_image[:, split_point:, :],
|
|
||||||
reshape_to_final=False)
|
|
||||||
|
|
||||||
left_frame = cv2.cvtColor(left_frame, cv2.COLOR_BGR2RGB)
|
|
||||||
right_frame = cv2.cvtColor(right_frame, cv2.COLOR_BGR2RGB)
|
|
||||||
msg.append({
|
|
||||||
'camera_name': details['cam_name'] + '_left',
|
|
||||||
'frame': left_frame,
|
|
||||||
'image_timestamp': timestamp
|
|
||||||
})
|
|
||||||
msg.append({
|
|
||||||
'camera_name': details['cam_name'] + '_right',
|
|
||||||
'frame': right_frame,
|
|
||||||
'image_timestamp': timestamp
|
|
||||||
})
|
|
||||||
|
|
||||||
else:
|
|
||||||
frame = resize_image(reshaped_image, reshape_to_final=False)
|
|
||||||
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
|
||||||
msg.append({
|
|
||||||
'camera_name': details['cam_name'],
|
|
||||||
'frame': frame,
|
|
||||||
'image_timestamp': timestamp
|
|
||||||
})
|
|
||||||
|
|
||||||
return msg
|
|
||||||
|
|
||||||
|
|
||||||
for x in range(img_scoring_queue.qsize()):
|
|
||||||
qu = img_scoring_queue.get()
|
|
||||||
print(qu['camera_name'], qu['frame'].shape)
|
|
||||||
cv2.imwrite(str(x) + '.jpg', qu['frame'])
|
|
||||||
2984
hailort.log
2984
hailort.log
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 495 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 198 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 176 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 222 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 185 KiB |
306
run_me.py
306
run_me.py
@@ -1,92 +1,15 @@
|
|||||||
import numpy as np
|
from common_code.settings import get_logger
|
||||||
from functools import partial
|
|
||||||
from hailo_platform import VDevice, HailoSchedulingAlgorithm, FormatType
|
from utils import StreamManager, run_model
|
||||||
|
import multiprocessing as mp
|
||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
|
logger = get_logger('live_inference',file_path = '/var/log/live_inference.log', stdout=True)
|
||||||
|
|
||||||
def resize_image(img_in, reshape_to_final=True):
|
all_cameras_config = {
|
||||||
if not isinstance(img_in, np.ndarray):
|
|
||||||
img_in = np.asarray(img_in)
|
|
||||||
max_l = 640
|
|
||||||
|
|
||||||
asp_rat = img_in.shape[0] / img_in.shape[1]
|
|
||||||
if asp_rat < 1:
|
|
||||||
output_size = [int(asp_rat * max_l), max_l]
|
|
||||||
else:
|
|
||||||
output_size = [max_l, int(max_l / asp_rat)]
|
|
||||||
|
|
||||||
im_arr_not_pad = cv2.resize(img_in, output_size[::-1])
|
|
||||||
pad_amt = [max_l, max_l] - np.asarray(im_arr_not_pad.shape[0:2])
|
|
||||||
|
|
||||||
left_pad, top_pad = (pad_amt / 2).astype(np.int64)
|
|
||||||
right_pad, bottom_pad = pad_amt - [left_pad, top_pad]
|
|
||||||
|
|
||||||
im_pass = np.zeros(shape=(max_l, max_l, 3), dtype=np.uint8)
|
|
||||||
im_pass[left_pad:(max_l - right_pad),
|
|
||||||
top_pad:(max_l - bottom_pad)] = (im_arr_not_pad)
|
|
||||||
data = im_pass
|
|
||||||
if reshape_to_final:
|
|
||||||
data = np.moveaxis(data, [2], [0])[None, :, :, :]
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def model_scoring_callback(completion_info, bindings, data):
|
|
||||||
if completion_info.exception:
|
|
||||||
# handle exception
|
|
||||||
pass
|
|
||||||
ff = bindings.output().get_buffer()
|
|
||||||
|
|
||||||
|
|
||||||
timeout_ms = 1000
|
|
||||||
|
|
||||||
params = VDevice.create_params()
|
|
||||||
params.scheduling_algorithm = HailoSchedulingAlgorithm.ROUND_ROBIN
|
|
||||||
import time
|
|
||||||
|
|
||||||
# The vdevice is used as a context manager ("with" statement) to ensure it's released on time.
|
|
||||||
with VDevice(params) as vdevice:
|
|
||||||
# Create an infer model from an HEF:
|
|
||||||
infer_model = vdevice.create_infer_model("yolov11l_inat.hef")
|
|
||||||
|
|
||||||
# Configure the infer model and create bindings for it
|
|
||||||
with infer_model.configure() as configured_infer_model:
|
|
||||||
bindings = configured_infer_model.create_bindings()
|
|
||||||
st = time.time()
|
|
||||||
for i in range(1):
|
|
||||||
# Set input and output buffers
|
|
||||||
buffer = inp # np.zeros(infer_model.input().shape).astype(np.uint8)
|
|
||||||
bindings.input().set_buffer(buffer)
|
|
||||||
|
|
||||||
output_array = np.zeros([infer_model.output().shape[0]
|
|
||||||
]).astype(np.float32)
|
|
||||||
bindings.output().set_buffer(output_array)
|
|
||||||
|
|
||||||
# Run synchronous inference and access the output buffers
|
|
||||||
configured_infer_model.run([bindings], timeout_ms)
|
|
||||||
buffer = bindings.output().get_buffer()
|
|
||||||
|
|
||||||
# Run asynchronous inference
|
|
||||||
job = configured_infer_model.run_async(
|
|
||||||
[bindings],
|
|
||||||
partial(example_callback, bindings=bindings, data=time.time()),
|
|
||||||
)
|
|
||||||
job.wait(timeout_ms)
|
|
||||||
|
|
||||||
# %%
|
|
||||||
import cv2
|
|
||||||
import time
|
|
||||||
import multiprocessing
|
|
||||||
import numpy as np
|
|
||||||
import ctypes
|
|
||||||
import shutil
|
|
||||||
from utils import *
|
|
||||||
|
|
||||||
cameras = {
|
|
||||||
"camera_sidefeeder": {
|
"camera_sidefeeder": {
|
||||||
'url': "rtsp://admin:marybear@192.168.1.157:554/h264Preview_01_sub",
|
'url': "rtsp://admin:marybear@192.168.1.157:554/h264Preview_01_sub",
|
||||||
'resolution': (480, 640, 3)
|
'resolution': (360, 640, 3)
|
||||||
},
|
},
|
||||||
"camera_driveway": {
|
"camera_driveway": {
|
||||||
'url': "rtsp://admin:marybear@192.168.1.152:554/h264Preview_01_sub",
|
'url': "rtsp://admin:marybear@192.168.1.152:554/h264Preview_01_sub",
|
||||||
@@ -96,7 +19,7 @@ cameras = {
|
|||||||
'url': "rtsp://admin:marybear@192.168.1.153:554/h264Preview_01_sub",
|
'url': "rtsp://admin:marybear@192.168.1.153:554/h264Preview_01_sub",
|
||||||
'resolution': (512, 896, 3)
|
'resolution': (512, 896, 3)
|
||||||
},
|
},
|
||||||
"camera_ptz_right": {
|
"camera_ptz": {
|
||||||
'url': "rtsp://admin:marybear@192.168.1.155:554/h264Preview_01_sub",
|
'url': "rtsp://admin:marybear@192.168.1.155:554/h264Preview_01_sub",
|
||||||
'resolution': (360, 640, 3)
|
'resolution': (360, 640, 3)
|
||||||
},
|
},
|
||||||
@@ -111,145 +34,104 @@ cameras = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cameras_config = dict()
|
||||||
|
k_c = 'camera_railing'
|
||||||
|
#cameras_config[k_c] = all_cameras_config[k_c]
|
||||||
|
cameras_config = all_cameras_config
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from functools import partial
|
|
||||||
|
|
||||||
cameras = dict()
|
cameras = dict()
|
||||||
for cam_name, details in cameras.items():
|
from random import random
|
||||||
rtsp_url = details['url']
|
img_scoring_queue = mp.Queue(maxsize = len(cameras_config)*2)
|
||||||
|
for cam_name, details in cameras_config.items():
|
||||||
|
rtsp_url = details['url']
|
||||||
|
if random() < -1:
|
||||||
|
rtsp_url = 'rtsp://admin:marybear@192.168.1.124'
|
||||||
|
print(f"Switching RTSP stream for {cam_name}")
|
||||||
resolution = details['resolution']
|
resolution = details['resolution']
|
||||||
cameras[cam_name] = StreamManager( rtsp_url, resolution, cam_name)
|
cameras[cam_name] = StreamManager(rtsp_url=rtsp_url,
|
||||||
|
resolution=resolution,
|
||||||
|
img_scoring_queue=img_scoring_queue,
|
||||||
|
camera_name=cam_name,
|
||||||
|
split_into_two=details.get(
|
||||||
|
|
||||||
|
'split_into_two', False))
|
||||||
|
cameras[cam_name].start_process()
|
||||||
|
logger.info(f'Started StreamManager for {cam_name}')
|
||||||
|
|
||||||
# %%
|
pp = mp.Process(target=run_model, args=(img_scoring_queue, ))
|
||||||
details['cam_name'] = cam_name
|
pp.start()
|
||||||
details['img_array'] = multiprocessing.Array(ctypes.c_uint8,
|
logger.info(f'Started model scoring process')
|
||||||
int(array_len),
|
|
||||||
lock=True)
|
|
||||||
details['img_timestamp'] = multiprocessing.Value(ctypes.c_double)
|
|
||||||
details['queue'] = multiprocessing.Queue()
|
|
||||||
details['rtsp_url'] = format_ffmpeg_decode_url(details['url']).split(" ")
|
|
||||||
details['process_func'] = partial(stream_wrapper,
|
|
||||||
details['resolution'],
|
|
||||||
details['rtsp_url'],
|
|
||||||
camera_name=cam_name,
|
|
||||||
queue=details['queue'],
|
|
||||||
img_array=details['img_array'],
|
|
||||||
img_timestamp=details['img_timestamp'])
|
|
||||||
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
p = multiprocessing.Process(target = details['process_func'])
|
|
||||||
details['process'] = p
|
|
||||||
p.start()
|
|
||||||
|
|
||||||
# %%
|
|
||||||
img_array = details['img_array']
|
|
||||||
img_timestamp = details['img_timestamp']
|
|
||||||
|
|
||||||
import time
|
|
||||||
with img_timestamp.get_lock():
|
|
||||||
img_timestamp.value = -1
|
|
||||||
details['queue'].put('get')
|
|
||||||
for i in range(1000):
|
|
||||||
val = img_timestamp.value
|
|
||||||
print(val)
|
|
||||||
if val > 0:
|
|
||||||
|
|
||||||
print('Done')
|
|
||||||
break
|
|
||||||
time.sleep(0.001)
|
|
||||||
|
|
||||||
|
|
||||||
# %%
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
details['queue'].put('get')
|
|
||||||
img_array = details['img_array']
|
|
||||||
img_timestamp = details['img_timestamp']
|
|
||||||
with img_array.get_lock(), img_timestamp.get_lock():
|
|
||||||
reshaped_image = np.frombuffer(details['img_array'].get_obj(),
|
|
||||||
dtype=np.uint8).reshape(
|
|
||||||
details['resolution'])
|
|
||||||
timestamp = img_timestamp.value
|
|
||||||
img_timestamp.value = -1
|
|
||||||
print('Writing for ' + cam_name + f' for {reshaped_image.shape}')
|
|
||||||
cv2.imwrite('images/'+ cam_name + '.jpg', reshaped_image)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# %%
|
# %%
|
||||||
import asyncio
|
|
||||||
|
|
||||||
img_scoring_queue = multiprocessing.Queue()
|
|
||||||
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
p = multiprocessing.Process(target=rtsp_stream_manager,
|
|
||||||
args=(cam_name, details['gst_pipeline_str'],
|
|
||||||
details['queue'], details['img_array'],
|
|
||||||
details['img_timestamp']))
|
|
||||||
details['process'] = p
|
|
||||||
|
|
||||||
asyncio.create_task(details['async_task'])
|
|
||||||
|
|
||||||
shape = (512, 896, 3)
|
|
||||||
|
|
||||||
asyncio.run(read_stream(shape, cmd))
|
|
||||||
|
|
||||||
import datetime as dt
|
|
||||||
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
details['process'].start()
|
|
||||||
# %%
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
details['queue'].put('restart')
|
|
||||||
# %%
|
|
||||||
for cam_name, details in cameras.items():
|
|
||||||
details['queue'].put('get')
|
|
||||||
|
|
||||||
if os.path.exists('images/'):
|
|
||||||
shutil.rmtree('images/')
|
|
||||||
|
|
||||||
os.makedirs('images/')
|
|
||||||
|
|
||||||
|
|
||||||
def create_score_message(details, reshaped_image, timestamp):
|
|
||||||
frames = list()
|
|
||||||
|
|
||||||
msg = list()
|
|
||||||
if details.get('split_into_two', False):
|
|
||||||
split_point = int(reshaped_image.shape[1] / 2)
|
|
||||||
left_frame = resize_image(reshaped_image[:, :split_point, :],
|
|
||||||
reshape_to_final=False)
|
|
||||||
right_frame = resize_image(reshaped_image[:, split_point:, :],
|
|
||||||
reshape_to_final=False)
|
|
||||||
|
|
||||||
left_frame = cv2.cvtColor(left_frame, cv2.COLOR_BGR2RGB)
|
|
||||||
right_frame = cv2.cvtColor(right_frame, cv2.COLOR_BGR2RGB)
|
|
||||||
msg.append({
|
|
||||||
'camera_name': details['cam_name'] + '_left',
|
|
||||||
'frame': left_frame,
|
|
||||||
'image_timestamp': timestamp
|
|
||||||
})
|
|
||||||
msg.append({
|
|
||||||
'camera_name': details['cam_name'] + '_right',
|
|
||||||
'frame': right_frame,
|
|
||||||
'image_timestamp': timestamp
|
|
||||||
})
|
|
||||||
|
|
||||||
else:
|
|
||||||
frame = resize_image(reshaped_image, reshape_to_final=False)
|
|
||||||
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
|
||||||
msg.append({
|
|
||||||
'camera_name': details['cam_name'],
|
|
||||||
'frame': frame,
|
|
||||||
'image_timestamp': timestamp
|
|
||||||
})
|
|
||||||
|
|
||||||
return msg
|
|
||||||
|
|
||||||
|
|
||||||
for x in range(img_scoring_queue.qsize()):
|
|
||||||
qu = img_scoring_queue.get()
|
iters = 0
|
||||||
print(qu['camera_name'], qu['frame'].shape)
|
while True:
|
||||||
cv2.imwrite(str(x) + '.jpg', qu['frame'])
|
for cam_name, obj in cameras.items():
|
||||||
|
logger.info(f'Asking {cam_name} process to score')
|
||||||
|
obj.score_frame_in_queue( save_to_disk = True)
|
||||||
|
# obj.score_frame_in_queue( save_to_disk = iters % 10 == 0)
|
||||||
|
obj.health_check()
|
||||||
|
|
||||||
|
iters+=1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# # %%
|
||||||
|
# from utils import species_list
|
||||||
|
# import pickle
|
||||||
|
# import json
|
||||||
|
# with open('crap.p','rb') as fw:
|
||||||
|
# dump = pickle.load(fw)
|
||||||
|
|
||||||
|
|
||||||
|
# camera_name = dump[1]['camera_name']
|
||||||
|
# timestamp = dump[1]['image_timestamp']
|
||||||
|
# ff = dump[0]
|
||||||
|
|
||||||
|
# has_scores = {idx:x for idx,x in enumerate(dump[0]) if len(x) > 0}
|
||||||
|
|
||||||
|
# score_dict = {}
|
||||||
|
|
||||||
|
# score_dict['timestamp'] = timestamp.timestamp()
|
||||||
|
# score_dict['scores'] = list()
|
||||||
|
|
||||||
|
# for idx, sc in has_scores.items():
|
||||||
|
# for r in sc:
|
||||||
|
# score_dict['scores'].append({'idx': idx, 'species': species_list[idx], 'boxes':r[0:4].tolist(), 'score': r[4].tolist()})
|
||||||
|
|
||||||
|
|
||||||
|
# def round_floats(obj, decimals=4):
|
||||||
|
# if isinstance(obj, float):
|
||||||
|
# return round(obj, decimals)
|
||||||
|
# elif isinstance(obj, dict):
|
||||||
|
# return {k: round_floats(v, decimals) for k, v in obj.items()}
|
||||||
|
# elif isinstance(obj, list):
|
||||||
|
# return [round_floats(item, decimals) for item in obj]
|
||||||
|
# return obj
|
||||||
|
# json_str = json.dumps(round_floats(score_dict))
|
||||||
|
|
||||||
|
|
||||||
|
# with open('/home/thebears/source/infer/scores/' + camera_name,'a') as ff:
|
||||||
|
# ff.write(json_str)
|
||||||
|
# ff.write('\n')
|
||||||
|
|
||||||
|
# import matplotlib.pyplot as plt
|
||||||
|
# plt.imshow(dump[1]['frame'])
|
||||||
|
# plt.show()
|
||||||
|
|
||||||
|
# # %%
|
||||||
|
# for cam_name, cls in cameras.items():
|
||||||
|
# ret = cls.capture_image()
|
||||||
|
# cv2.imwrite('images/' + cam_name + '.jpg', ret['image'])
|
||||||
|
|
||||||
|
|||||||
298
utils.py
298
utils.py
@@ -1,112 +1,220 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import numpy as np
|
from common_code.settings import LogColorize
|
||||||
|
import concurrent.futures
|
||||||
|
|
||||||
|
import string
|
||||||
|
from random import choices
|
||||||
|
from urllib import parse
|
||||||
|
from io import BytesIO
|
||||||
|
import requests
|
||||||
|
import cv2
|
||||||
|
import queue
|
||||||
|
|
||||||
|
import logging
|
||||||
import struct
|
import struct
|
||||||
import re
|
import re
|
||||||
import pickle
|
import pickle
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
|
from functools import partial
|
||||||
|
import cv2
|
||||||
import time
|
import time
|
||||||
import numpy
|
import multiprocessing
|
||||||
|
import threading
|
||||||
|
import numpy as np
|
||||||
|
import ctypes
|
||||||
|
import shutil
|
||||||
|
import hashlib
|
||||||
|
from hailo_platform import VDevice, HailoSchedulingAlgorithm, FormatType
|
||||||
|
import pickle
|
||||||
|
import json
|
||||||
|
import redis
|
||||||
|
import os
|
||||||
|
pfm = LogColorize.score_obj_det_embed
|
||||||
|
|
||||||
|
with open('/home/thebears/source/infer/species_list','r') as sl:
|
||||||
|
species_list = [x for x in sl.read().split('\n') if len(x) > 0]
|
||||||
|
|
||||||
|
r = redis.Redis('localhost',port=6379, db=14)
|
||||||
|
|
||||||
|
logger = logging.getLogger('live_inference')
|
||||||
|
|
||||||
|
def resize_image(img_in, reshape_to_final=False):
|
||||||
|
if not isinstance(img_in, np.ndarray):
|
||||||
|
img_in = np.asarray(img_in)
|
||||||
|
max_l = 640
|
||||||
|
|
||||||
|
asp_rat = img_in.shape[0] / img_in.shape[1]
|
||||||
|
if asp_rat < 1:
|
||||||
|
output_size = [int(asp_rat * max_l), max_l]
|
||||||
|
else:
|
||||||
|
output_size = [max_l, int(max_l / asp_rat)]
|
||||||
|
|
||||||
|
im_arr_not_pad = cv2.resize(img_in, output_size[::-1])
|
||||||
|
pad_amt = [max_l, max_l] - np.asarray(im_arr_not_pad.shape[0:2])
|
||||||
|
left_pad, top_pad = (pad_amt / 2).astype(np.int64)
|
||||||
|
right_pad, bottom_pad = pad_amt - [left_pad, top_pad]
|
||||||
|
|
||||||
|
im_pass = np.zeros(shape=(max_l, max_l, 3), dtype=np.uint8)
|
||||||
|
im_pass[left_pad:(max_l - right_pad),
|
||||||
|
top_pad:(max_l - bottom_pad)] = (im_arr_not_pad)
|
||||||
|
data = im_pass
|
||||||
|
if reshape_to_final:
|
||||||
|
data = np.moveaxis(data, [2], [0])[None, :, :, :]
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
class StreamManager():
|
def model_scoring_callback(completion_info, bindings, data):
|
||||||
def __init__(self, rtsp_url, resolution, camera_name = 'N/A'):
|
if completion_info.exception:
|
||||||
self.cam_name = cam_name
|
pass
|
||||||
|
ff = bindings.output().get_buffer()
|
||||||
|
camera_name = data['camera_name']
|
||||||
|
timestamp = data['image_timestamp']
|
||||||
|
hash_value = data['image_hash']
|
||||||
|
dump_model_results_to_json( camera_name, timestamp, ff, hash_value)
|
||||||
|
|
||||||
|
def round_floats(obj, decimals=4):
|
||||||
self.array_len = np.prod(resolution)
|
if isinstance(obj, float):
|
||||||
self.cam_name = cam_name
|
return round(obj, decimals)
|
||||||
self.img_array = multiprocessing.Array(ctypes.c_uint8,
|
elif isinstance(obj, dict):
|
||||||
int(array_len),
|
return {k: round_floats(v, decimals) for k, v in obj.items()}
|
||||||
lock=True)
|
elif isinstance(obj, list):
|
||||||
self.img_timestamp = multiprocessing.Value(ctypes.c_double)
|
return [round_floats(item, decimals) for item in obj]
|
||||||
self.queue = multiprocessing.Queue()
|
return obj
|
||||||
self.rtsp_url = format_ffmpeg_decode_url(rtsp_url).split(" ")
|
|
||||||
self.process_func = partial(stream_wrapper,
|
|
||||||
self.resolution,
|
|
||||||
self.rtsp_url,
|
|
||||||
camera_name=cam_name,
|
|
||||||
queue=self.queue,
|
|
||||||
img_array=self.img_array,
|
|
||||||
img_timestamp=self.img_timestamp))
|
|
||||||
|
|
||||||
|
|
||||||
def get_next_bitmap( byte_stream, shape):
|
|
||||||
numel = np.prod(shape)
|
|
||||||
string_find = b'BM' + struct.pack('<I',numel+54)
|
|
||||||
fcf = [m.start() for m in re.finditer(re.escape(string_find), byte_stream)]
|
|
||||||
for start_index in fcf:
|
|
||||||
end_index = start_index + 60+numel
|
|
||||||
frame_data_with_header = byte_stream[start_index:end_index]
|
|
||||||
header = frame_data_with_header[:60]
|
|
||||||
frame = frame_data_with_header[60:]
|
|
||||||
nf = np.frombuffer(frame, dtype=np.uint8)
|
|
||||||
if len(nf) != numel:
|
|
||||||
return None, None
|
|
||||||
pic = np.reshape(nf, shape)
|
|
||||||
pic = pic[::-1,:,:]
|
|
||||||
if len(nf) == numel:
|
|
||||||
return pic
|
|
||||||
|
|
||||||
|
|
||||||
def stream_wrapper( shape, cmd, camera_name = None, queue = None, img_array = None, img_timestamp = None):
|
|
||||||
print('Starting wrapper')
|
|
||||||
func = read_stream( shape, cmd, camera_name = camera_name, queue = queue, img_array = img_array, img_timestamp = img_timestamp)
|
|
||||||
asyncio.run(func)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def read_stream( shape, cmd, camera_name = None, queue = None, img_array = None, img_timestamp = None):
|
def dump_model_results_to_json(camera_name, timestamp, output_array, hash_value):
|
||||||
print('Starting stream')
|
has_scores = {idx:x for idx,x in enumerate(output_array) if len(x) > 0}
|
||||||
byte_buffer = b''
|
score_dict = {}
|
||||||
bytes_read = (np.prod(shape)+60)*2
|
score_dict['timestamp'] = timestamp
|
||||||
print(cmd)
|
score_dict['scores'] = list()
|
||||||
process = await asyncio.create_subprocess_exec(*cmd,
|
score_dict['image_hash'] = hash_value
|
||||||
stdout=asyncio.subprocess.PIPE,
|
for idx, sc in has_scores.items():
|
||||||
stderr=asyncio.subprocess.PIPE
|
for r in sc:
|
||||||
)
|
score_dict['scores'].append({'idx': idx, 'species': species_list[idx], 'boxes':r[0:4].tolist(), 'score': r[4].tolist()})
|
||||||
try:
|
|
||||||
|
|
||||||
|
json_str = json.dumps(round_floats(score_dict))
|
||||||
|
|
||||||
|
|
||||||
|
with open('/home/thebears/source/infer/scores/' + camera_name,'a') as ff:
|
||||||
|
ff.write(json_str)
|
||||||
|
ff.write('\n')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def run_model(img_scoring_queue):
|
||||||
|
timeout_ms = 1000
|
||||||
|
logger.info('Starting model scoring process')
|
||||||
|
params = VDevice.create_params()
|
||||||
|
params.scheduling_algorithm = HailoSchedulingAlgorithm.ROUND_ROBIN
|
||||||
|
with VDevice(params) as vdevice:
|
||||||
|
infer_model = vdevice.create_infer_model("yolov11l_inat.hef")
|
||||||
|
logger.info('Loaded model')
|
||||||
|
with infer_model.configure() as configured_infer_model:
|
||||||
|
bindings = configured_infer_model.create_bindings()
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
# Use get with timeout for multiprocessing queue
|
||||||
|
res = img_scoring_queue.get(timeout=1.0)
|
||||||
|
r.set('model_inference_heartbeat',time.time())
|
||||||
|
inp = res['frame']
|
||||||
|
|
||||||
|
res_send = {'camera_name': res['camera_name'], 'image_timestamp': res['image_timestamp'], 'image_hash':res['image_hash']}
|
||||||
|
logger.info(f'Running inference for {res_send}')
|
||||||
|
r.set('model_inference_started',str(res_send))
|
||||||
|
|
||||||
|
bindings.input().set_buffer(inp)
|
||||||
|
output_array = np.zeros([infer_model.output().shape[0]]).astype(np.float32)
|
||||||
|
bindings.output().set_buffer(output_array)
|
||||||
|
|
||||||
|
configured_infer_model.run([bindings], timeout_ms)
|
||||||
|
|
||||||
|
job = configured_infer_model.run_async(
|
||||||
|
[bindings],
|
||||||
|
partial(model_scoring_callback, bindings=bindings, data=res_send),
|
||||||
|
)
|
||||||
|
r.set('model_inference_finished',str(res_send))
|
||||||
|
try:
|
||||||
|
job.wait(timeout_ms)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(str(e))
|
||||||
|
except:
|
||||||
|
# Handle both queue.Empty and multiprocessing timeout
|
||||||
|
continue
|
||||||
|
|
||||||
|
class SnapManager():
|
||||||
|
def __init__(self, ip, url_api, username, password, camera_name, msg_queue=None, img_scoring_queue=None, split_into_two=False, **kwargs):
|
||||||
|
self.ip = ip
|
||||||
|
self.url_api = url_api
|
||||||
|
self.username = username
|
||||||
|
self.password = password
|
||||||
|
self.camera_name = camera_name
|
||||||
|
self.split_into_two = split_into_two
|
||||||
|
n self.msg_queue = msg_queue
|
||||||
|
self.img_scoring_queue = img_scoring_queue
|
||||||
|
logger.info(f"{self.camera_name}: initialized")
|
||||||
|
|
||||||
|
def format_image_for_model(self, image, timestamp):
|
||||||
|
msg = list()
|
||||||
|
if self.split_into_two:
|
||||||
|
split_point = int(image.shape[1] / 2)
|
||||||
|
left_frame = resize_image(image[:, :split_point, :])
|
||||||
|
right_frame = resize_image(image[:, split_point:, :])
|
||||||
|
|
||||||
|
msg.append({
|
||||||
|
'camera_name': self.camera_name + '_left',
|
||||||
|
'frame': left_frame,
|
||||||
|
'image_timestamp': timestamp,
|
||||||
|
'image_hash': hashlib.sha1(left_frame.tobytes()).hexdigest()
|
||||||
|
})
|
||||||
|
msg.append({
|
||||||
|
'camera_name': self.camera_name + '_right',
|
||||||
|
'frame': right_frame,
|
||||||
|
'image_timestamp': timestamp,
|
||||||
|
'image_hash': hashlib.sha1(right_frame.tobytes()).hexdigest()
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
frame = resize_image(image)
|
||||||
|
msg.append({
|
||||||
|
'camera_name': self.camera_name,
|
||||||
|
'frame': frame,
|
||||||
|
'image_timestamp': timestamp,
|
||||||
|
'image_hash': hashlib.sha1(frame.tobytes()).hexdigest()
|
||||||
|
})
|
||||||
|
return msg
|
||||||
|
|
||||||
|
def capture_and_prepare(self):
|
||||||
|
img = get_snap(self.username, self.password, self.url_api, self.camera_name)
|
||||||
|
if img is not None:
|
||||||
|
timestamp = time.time()
|
||||||
|
return self.format_image_for_model(img, timestamp)
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def run_forever(self):
|
||||||
while True:
|
while True:
|
||||||
# Read up to 65KB at a time
|
try:
|
||||||
chunk = await process.stdout.read(bytes_read)
|
msg = self.msg_queue.get(timeout=0.1)
|
||||||
byte_buffer += chunk
|
|
||||||
diff = len(byte_buffer) - bytes_read
|
|
||||||
# print(len(byte_buffer))
|
|
||||||
if diff > 0:
|
|
||||||
byte_buffer = byte_buffer[diff::]
|
|
||||||
|
|
||||||
|
|
||||||
if not queue.empty():
|
|
||||||
msg = queue.get_nowait()
|
|
||||||
print('got message! ' + str( msg))
|
|
||||||
if msg == 'exit':
|
if msg == 'exit':
|
||||||
return
|
break
|
||||||
|
if msg == 'save_image':
|
||||||
|
|
||||||
if msg == 'get':
|
if msg == 'get':
|
||||||
print('doing get!')
|
logger.info(f'Processing capture for {self.camera_name}')
|
||||||
frame = get_next_bitmap(byte_buffer, shape)
|
model_msgs = self.capture_and_prepare()
|
||||||
with img_timestamp.get_lock(), img_array.get_lock():
|
for model_msg in model_msgs:
|
||||||
if frame is None:
|
# Use put_nowait for multiprocessing queue to avoid blocking
|
||||||
print(f"Read empty frame for {camera_name}")
|
try:
|
||||||
img_array[:] = 0
|
self.img_scoring_queue.put_nowait(model_msg)
|
||||||
img_timestamp.value = 0
|
except:
|
||||||
else:
|
# Queue full, skip this message
|
||||||
print(f"Read frame for {camera_name} at {dt.datetime.now()}")
|
logger.warning(f"Model queue full, dropping message from {self.camera_name}")
|
||||||
img_array[:] = frame.flatten()[:]
|
except queue.Empty:
|
||||||
img_timestamp.value = time.time()
|
pass
|
||||||
|
|
||||||
|
def start_snap_manager(**kwargs):
|
||||||
except asyncio.CancelledError:
|
obj = SnapManager(**kwargs)
|
||||||
print('Cancelled Error')
|
obj.run_forever()
|
||||||
process.kill()
|
|
||||||
await process.wait()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def format_gst_url(rtsp_url):
|
|
||||||
gst_pipeline = f"rtspsrc location={rtsp_url} latency=50 ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! appsink max-buffers=1 drop=true"
|
|
||||||
return gst_pipeline
|
|
||||||
|
|
||||||
def format_ffmpeg_decode_url(rtsp_url):
|
|
||||||
cmd = f"ffmpeg -rtsp_transport tcp -i {rtsp_url} -f image2pipe -vcodec bmp -an pipe:1"
|
|
||||||
return cmd
|
|
||||||
|
|||||||
Reference in New Issue
Block a user