bump
This commit is contained in:
BIN
__pycache__/utils.cpython-311.pyc
Normal file
BIN
__pycache__/utils.cpython-311.pyc
Normal file
Binary file not shown.
337
analyze_dump.py
Normal file
337
analyze_dump.py
Normal 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)
|
||||||
255
flycheck_run_me.py
Normal file
255
flycheck_run_me.py
Normal 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
BIN
images/camera_backyard.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 495 KiB |
BIN
images/camera_driveway.jpg
Normal file
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
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
BIN
images/camera_railing.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 222 KiB |
BIN
images/camera_side.jpg
Normal file
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
BIN
images/camera_wrenwatch.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 185 KiB |
170
run_me.py
170
run_me.py
@@ -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,65 +111,92 @@ 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,7 +207,6 @@ 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/')
|
||||||
|
|
||||||
@@ -193,47 +219,37 @@ def create_score_message( details, reshaped_image, timestamp):
|
|||||||
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'])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
112
utils.py
Normal file
112
utils.py
Normal 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
|
||||||
Reference in New Issue
Block a user