This commit is contained in:
The Bears
2025-10-27 14:10:54 -04:00
parent 73a2aead5f
commit e79a9f0458
23 changed files with 906 additions and 86 deletions

BIN
0.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

BIN
1.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

BIN
2.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

BIN
3.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

BIN
4.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

BIN
5.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

BIN
6.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

BIN
FRAME.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

337
analyze_dump.py Normal file
View File

@@ -0,0 +1,337 @@
import pickle
with open('/home/thebears/source/infer/dump','rb') as ff:
dump = pickle.load(ff)
# %%
import av
import numpy as np
#def rtp_to_matrix(rtp_packets):
if True:
"""Convert list of RTP packets to image matrix"""
# Create codec context (adjust codec based on your stream)
codec = av.CodecContext.create('h264', 'r') # or 'h265', 'mjpeg', etc.
frames = []
for _,rtp_packet in ts_data.items():
# Extract payload (skip RTP header - usually 12 bytes)
payload = rtp_packet
# Create packet
print(len(payload))
packet = av.Packet(payload)
try:
# Decode
for frame in codec.decode(packet):
# Convert to numpy array
img = frame.to_ndarray(format='bgr24')
frames.append(img)
except Exception as e:
print(f"Decode error: {e}")
continue
# Flush decoder
for frame in codec.decode(None):
img = frame.to_ndarray(format='bgr24')
frames.append(img)
# Usage
# rtp_packets = [packet1, packet2, ...] # Your raw RTP packets
# matrices = rtp_to_matrix(rtp_packets)
# %%
import subprocess
import numpy as np
import cv2
from io import BytesIO
class RTPDepayloader:
def __init__(self, payload_type):
"""
payload_type: 96=H264, 26=JPEG, etc.
"""
self.payload_type = payload_type
self.buffer = bytearray()
def parse_rtp_header(self, packet):
"""Parse RTP header and return payload"""
if len(packet) < 12:
return None
# RTP Header structure (12 bytes minimum)
# Byte 0: V(2), P(1), X(1), CC(4)
# Byte 1: M(1), PT(7)
# Bytes 2-3: Sequence number
# Bytes 4-7: Timestamp
# Bytes 8-11: SSRC
version = (packet[0] >> 6) & 0x03
padding = (packet[0] >> 5) & 0x01
extension = (packet[0] >> 4) & 0x01
csrc_count = packet[0] & 0x0F
marker = (packet[1] >> 7) & 0x01
payload_type = packet[1] & 0x7F
sequence = int.from_bytes(packet[2:4], 'big')
timestamp = int.from_bytes(packet[4:8], 'big')
# Calculate header size
header_size = 12 + (csrc_count * 4)
if extension:
if len(packet) < header_size + 4:
return None
ext_len = int.from_bytes(packet[header_size+2:header_size+4], 'big') * 4
header_size += 4 + ext_len
# Return payload
payload = packet[header_size:]
return {
'payload': payload,
'marker': marker,
'sequence': sequence,
'timestamp': timestamp,
'payload_type': payload_type
}
def depayload_h264(self, rtp_packets):
"""Depayload H.264 RTP packets to NAL units"""
nal_units = bytearray()
for packet in rtp_packets:
parsed = self.parse_rtp_header(packet)
if not parsed:
continue
payload = parsed['payload']
if len(payload) == 0:
continue
# H.264 RTP payload format (RFC 6184)
nal_unit_type = payload[0] & 0x1F
if nal_unit_type >= 1 and nal_unit_type <= 23:
# Single NAL unit
nal_units.extend(b'\x00\x00\x00\x01') # Start code
nal_units.extend(payload)
elif nal_unit_type == 28:
# FU-A (Fragmentation Unit)
fu_header = payload[1]
start = (fu_header >> 7) & 0x01
end = (fu_header >> 6) & 0x01
nal_type = fu_header & 0x1F
if start:
# Reconstruct NAL header
nal_header = (payload[0] & 0xE0) | nal_type
nal_units.extend(b'\x00\x00\x00\x01')
nal_units.append(nal_header)
nal_units.extend(payload[2:])
return bytes(nal_units)
def decode_h264_to_matrix(h264_data):
"""Decode H.264 bitstream to image matrix using FFmpeg"""
# Use FFmpeg to decode
process = subprocess.Popen([
'ffmpeg',
'-f', 'h264',
'-i', 'pipe:0',
'-f', 'rawvideo',
'-pix_fmt', 'bgr24',
'pipe:1'
], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate(input=h264_data)
# You need to know dimensions or parse from SPS
# For now, assume 1920x1080
width, height = 1920, 1080
if len(stdout) >= width * height * 3:
frame = np.frombuffer(stdout[:width*height*3], dtype=np.uint8)
frame = frame.reshape((height, width, 3))
return frame
return None
# Usage
rtp_packets = [bytes(x) for x in dump]
depayloader = RTPDepayloader(payload_type=96)
# rtp_packets = [...] # Your raw RTP packets
h264_stream = depayloader.depayload_h264(rtp_packets)
matrix = decode_h264_to_matrix(h264_stream)
# %%
bts = b''
for i in range(10000):
bts+=process.stdout.read(1024)
print(i)
# %%
with open('dumpb','wb') as ff:
ff.write(bts)
# %%
import re
pattern = b'BM'
fcf = [m.start() for m in re.finditer(re.escape(pattern), bts)]
# %%
with open('dumpb','rb') as ff:
byte_stream = ff.read()[10:]
import struct
import numpy as np
import cv2
# %%
import struct
def read_bmp_frames(stream):
"""Read individual BMP frames from a stream."""
while True:
# Read BMP signature (2 bytes)
signature = stream.read(2)
if len(signature) < 2:
break
if signature != b'BM':
print(f"Warning: Expected 'BM', got {signature}")
break
# Read file size (4 bytes, little-endian)
size_bytes = stream.read(4)
if len(size_bytes) < 4:
break
file_size = struct.unpack('<I', size_bytes)[0]
# Read the rest of the frame
remaining_size = file_size - 6 # Already read 6 bytes
frame_data = stream.read(remaining_size)
if len(frame_data) < remaining_size:
break
# Complete frame
complete_frame = signature + size_bytes + frame_data
yield complete_frame
# Usage
import subprocess as sp
cmd = "ffmpeg -rtsp_transport tcp -i rtsp://admin:marybear@192.168.1.153:554/h264Preview_01_sub -f image2pipe -vcodec bmp -an pipe:1"
# process = sp.Popen(
# cmd.split(" "),
# stdout=sp.PIPE,
# stderr=sp.PIPE,
# bufsize =512*896*3*3
# )
import asyncio
import subprocess
async def read_stream():
"""Read subprocess output asynchronously."""
process = await asyncio.create_subprocess_exec(*cmd.split(" "),
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
frame_count = 0
try:
while True:
# Read up to 65KB at a time
chunk = await process.stdout.read(65536)
print('chunk')
if not chunk:
break
frame_count += len(chunk)
print(f"Read {len(chunk)} bytes (total: {frame_count})")
except asyncio.CancelledError:
process.kill()
await process.wait()
return frame_count
# Run
frame_count = asyncio.run(read_stream())
# %%
# %%
import numpy as np
fr = next(gen)
import cv2
# %%
import av
import numpy as np
def rtp_to_matrix(rtp_packets):
"""Convert list of RTP packets to image matrix"""
# Create codec context (adjust codec based on your stream)
codec = av.CodecContext.create('h264', 'r') # or 'h265', 'mjpeg', etc.
frames = []
for rtp_packet in rtp_packets:
# Extract payload (skip RTP header - usually 12 bytes)
payload = rtp_packet[12:]
# Create packet
packet = av.Packet(payload)
try:
# Decode
for frame in codec.decode(packet):
# Convert to numpy array
img = frame.to_ndarray(format='bgr24')
frames.append(img)
except Exception as e:
print(f"Decode error: {e}")
continue
# Flush decoder
for frame in codec.decode(None):
img = frame.to_ndarray(format='bgr24')
frames.append(img)
return frames
# Usage
# rtp_packets = [packet1, packet2, ...] # Your raw RTP packets
# matrices = rtp_to_matrix(rtp_packets)

BIN
dump Normal file

Binary file not shown.

BIN
dumpb Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 MiB

100
ff.b Normal file

File diff suppressed because one or more lines are too long

255
flycheck_run_me.py Normal file
View File

@@ -0,0 +1,255 @@
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'])

BIN
images/camera_backyard.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 495 KiB

BIN
images/camera_driveway.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

BIN
images/camera_ptz_right.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

BIN
images/camera_railing.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

BIN
images/camera_side.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
images/camera_wrenwatch.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

188
run_me.py
View File

@@ -2,7 +2,6 @@ import numpy as np
from functools import partial from functools import partial
from hailo_platform import VDevice, HailoSchedulingAlgorithm, FormatType from hailo_platform import VDevice, HailoSchedulingAlgorithm, FormatType
import cv2 import cv2
import numpy as np import numpy as np
@@ -33,7 +32,6 @@ def resize_image(img_in, reshape_to_final=True):
return data return data
def model_scoring_callback(completion_info, bindings, data): def model_scoring_callback(completion_info, bindings, data):
if completion_info.exception: if completion_info.exception:
# handle exception # handle exception
@@ -83,9 +81,11 @@ import multiprocessing
import numpy as np import numpy as np
import ctypes import ctypes
import shutil import shutil
from utils import *
cameras = { cameras = {
"camera_side": { "camera_sidefeeder": {
'url': "rtsp://admin:marybear@192.168.1.151:554/h264Preview_01_sub", 'url': "rtsp://admin:marybear@192.168.1.157:554/h264Preview_01_sub",
'resolution': (480, 640, 3) 'resolution': (480, 640, 3)
}, },
"camera_driveway": { "camera_driveway": {
@@ -111,66 +111,93 @@ cameras = {
}, },
} }
# # %%
# import os
# os.environ['OPENCV_FFMPEG_CAPTURE_OPTIONS'] = 'rtsp_transport;udp'
# cap = cv2.VideoCapture(cameras['camera_railing']['url'])
# # %%
# while True:
# _, frame = cap.read()
# # %%
# _, frame = cap.read()
# cv2.imwrite('FRAME.jpg', frame)
# # %%
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
from functools import partial
cameras = dict()
for cam_name, details in cameras.items(): for cam_name, details in cameras.items():
array_len = np.prod(details['resolution']) rtsp_url = details['url']
resolution = details['resolution']
cameras[cam_name] = StreamManager( rtsp_url, resolution, cam_name)
# %%
details['cam_name'] = cam_name details['cam_name'] = cam_name
details['img_array'] = multiprocessing.Array(ctypes.c_uint8, details['img_array'] = multiprocessing.Array(ctypes.c_uint8,
int(array_len), lock = True) int(array_len),
lock=True)
details['img_timestamp'] = multiprocessing.Value(ctypes.c_double) details['img_timestamp'] = multiprocessing.Value(ctypes.c_double)
details['queue'] = multiprocessing.Queue() details['queue'] = multiprocessing.Queue()
details['gst_pipeline_str'] = format_gst_url(details['url']) 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)
import datetime as dt # %%
def rtsp_stream_manager( camera_name, gst_pipeline_str, queue, img_array, img_timestamp): for cam_name, details in cameras.items():
capture_handle = cv2.VideoCapture(gst_pipeline_str, cv2.CAP_GSTREAMER) details['queue'].put('get')
while True: img_array = details['img_array']
if not queue.empty(): img_timestamp = details['img_timestamp']
msg = queue.get_nowait() with img_array.get_lock(), img_timestamp.get_lock():
if msg == 'get': reshaped_image = np.frombuffer(details['img_array'].get_obj(),
ret, frame = capture_handle.read() dtype=np.uint8).reshape(
with img_timestamp.get_lock(), img_array.get_lock(): details['resolution'])
if frame is None: timestamp = img_timestamp.value
print(f"Read empty frame for {camera_name}") img_timestamp.value = -1
img_array[:] = 0 print('Writing for ' + cam_name + f' for {reshaped_image.shape}')
img_timestamp.value = 0 cv2.imwrite('images/'+ cam_name + '.jpg', reshaped_image)
else:
print(f"Read frame for {camera_name} at {dt.datetime.now()}")
img_array[:] = frame.flatten()[:]
img_timestamp.value = time.time() # %%
elif msg == 'restart': import asyncio
print('Restarting')
capture_handle = cv2.VideoCapture(gst_pipeline_str, cv2.CAP_GSTREAMER)
elif msg == 'exit':
print('Exiting')
return
img_scoring_queue = multiprocessing.Queue() img_scoring_queue = multiprocessing.Queue()
for cam_name, details in cameras.items(): for cam_name, details in cameras.items():
p = multiprocessing.Process(target=rtsp_stream_manager, p = multiprocessing.Process(target=rtsp_stream_manager,
args=(cam_name, details['gst_pipeline_str'], args=(cam_name, details['gst_pipeline_str'],
details['queue'], details['img_array'], details['img_timestamp'])) details['queue'], details['img_array'],
details['img_timestamp']))
details['process'] = p 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(): for cam_name, details in cameras.items():
details['process'].start() details['process'].start()
# %% # %%
@@ -180,60 +207,49 @@ for cam_name, details in cameras.items():
for cam_name, details in cameras.items(): for cam_name, details in cameras.items():
details['queue'].put('get') details['queue'].put('get')
if os.path.exists('images/'): if os.path.exists('images/'):
shutil.rmtree('images/') shutil.rmtree('images/')
os.makedirs('images/') os.makedirs('images/')
def create_score_message( details, reshaped_image, timestamp): def create_score_message(details, reshaped_image, timestamp):
frames = list() frames = list()
msg = list() msg = list()
if details.get('split_into_two', False): if details.get('split_into_two', False):
split_point = int(reshaped_image.shape[1]/2) split_point = int(reshaped_image.shape[1] / 2)
left_frame = resize_image(reshaped_image[:,:split_point,:], reshape_to_final = False) left_frame = resize_image(reshaped_image[:, :split_point, :],
right_frame = resize_image(reshaped_image[:,split_point:,:], reshape_to_final = False) 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) left_frame = cv2.cvtColor(left_frame, cv2.COLOR_BGR2RGB)
right_frame = cv2.cvtColor(right_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({
msg.append({'camera_name': details['cam_name']+'_right', 'frame': right_frame, 'image_timestamp': timestamp}) '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: else:
frame = resize_image(reshaped_image, reshape_to_final = False) frame = resize_image(reshaped_image, reshape_to_final=False)
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
msg.append({'camera_name': details['cam_name'], 'frame': frame, 'image_timestamp': timestamp}) msg.append({
'camera_name': details['cam_name'],
'frame': frame,
'image_timestamp': timestamp
})
return msg return msg
for cam_name, details in cameras.items():
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
for msg in create_score_message(details, reshaped_image, timestamp):
img_scoring_queue.put(msg)
print('Writing for ' + cam_name + f' for {reshaped_image.shape}')
# cv2.imwrite('images/'+ cam_name + '.jpg', reshaped_image)
for x in range(img_scoring_queue.qsize()): for x in range(img_scoring_queue.qsize()):
qu = img_scoring_queue.get() qu = img_scoring_queue.get()
print(qu['camera_name'],qu['frame'].shape) print(qu['camera_name'], qu['frame'].shape)
cv2.imwrite(str(x)+'.jpg', qu['frame']) cv2.imwrite(str(x) + '.jpg', qu['frame'])

BIN
test.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

112
utils.py Normal file
View File

@@ -0,0 +1,112 @@
import asyncio
import numpy as np
import struct
import re
import pickle
import datetime as dt
import time
import numpy
class StreamManager():
def __init__(self, rtsp_url, resolution, camera_name = 'N/A'):
self.cam_name = cam_name
self.array_len = np.prod(resolution)
self.cam_name = cam_name
self.img_array = multiprocessing.Array(ctypes.c_uint8,
int(array_len),
lock=True)
self.img_timestamp = multiprocessing.Value(ctypes.c_double)
self.queue = multiprocessing.Queue()
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):
print('Starting stream')
byte_buffer = b''
bytes_read = (np.prod(shape)+60)*2
print(cmd)
process = await asyncio.create_subprocess_exec(*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
try:
while True:
# Read up to 65KB at a time
chunk = await process.stdout.read(bytes_read)
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':
return
if msg == 'get':
print('doing get!')
frame = get_next_bitmap(byte_buffer, shape)
with img_timestamp.get_lock(), img_array.get_lock():
if frame is None:
print(f"Read empty frame for {camera_name}")
img_array[:] = 0
img_timestamp.value = 0
else:
print(f"Read frame for {camera_name} at {dt.datetime.now()}")
img_array[:] = frame.flatten()[:]
img_timestamp.value = time.time()
except asyncio.CancelledError:
print('Cancelled Error')
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