This commit is contained in:
The Bears
2025-10-31 21:15:14 -04:00
parent 09ed1b8c97
commit d3f2c5e170
6 changed files with 378 additions and 8 deletions

Binary file not shown.

View File

@@ -4703,4 +4703,25 @@
[2025-10-31 15:59:20.277] [277301] [HailoRT] [info] [pipeline.cpp:891] [print_deep_description] EntryPushQEl0yolov11l_inat/input_layer1 | inputs: user | outputs: PreInferEl3yolov11l_inat/input_layer1(running in thread_id: 277320) [2025-10-31 15:59:20.277] [277301] [HailoRT] [info] [pipeline.cpp:891] [print_deep_description] EntryPushQEl0yolov11l_inat/input_layer1 | inputs: user | outputs: PreInferEl3yolov11l_inat/input_layer1(running in thread_id: 277320)
[2025-10-31 15:59:20.277] [277301] [HailoRT] [info] [pipeline.cpp:891] [print_deep_description] PreInferEl3yolov11l_inat/input_layer1 | inputs: EntryPushQEl0yolov11l_inat/input_layer1[0] | outputs: PushQEl3yolov11l_inat/input_layer1 [2025-10-31 15:59:20.277] [277301] [HailoRT] [info] [pipeline.cpp:891] [print_deep_description] PreInferEl3yolov11l_inat/input_layer1 | inputs: EntryPushQEl0yolov11l_inat/input_layer1[0] | outputs: PushQEl3yolov11l_inat/input_layer1
[2025-10-31 15:59:20.277] [277301] [HailoRT] [info] [pipeline.cpp:891] [print_deep_description] PushQEl3yolov11l_inat/input_layer1 | inputs: PreInferEl3yolov11l_inat/input_layer1[0] | outputs: AsyncHwEl(running in thread_id: 277321) [2025-10-31 15:59:20.277] [277301] [HailoRT] [info] [pipeline.cpp:891] [print_deep_description] PushQEl3yolov11l_inat/input_layer1 | inputs: PreInferEl3yolov11l_inat/input_layer1[0] | outputs: AsyncHwEl(running in thread_id: 277321)
[2025-10-31 15:59:20.277] [277301] [HailoRT] [info] [pipeline.cpp:891] [print_deep_description] AsyncHwEl | inputs: PushQEl3yolov11l_inat/input_layer1[0] | outputs: MultiPushQEl0YOLOV8-Post-Process MultiPushQEl0YOLOV8-Post-Process MultiPushQEl0YOLOV8-Post-Process MultiPushQEl0YOLOV8-Post-Pro [2025-10-31 15:59:20.277] [277301] [HailoRT] [info] [pipeline.cpp:891] [print_deep_description] AsyncHwEl | inputs: PushQEl3yolov11l_inat/input_layer1[0] | outputs: MultiPushQEl0YOLOV8-Post-Process MultiPushQEl0YOLOV8-Post-Process MultiPushQEl0YOLOV8-Post-Process MultiPushQEl0YOLOV8-Post-Pro[2025-10-31 20:58:46.509] [278956] [HailoRT] [info] [vdevice.cpp:523] [create] Creating vdevice with params: device_count: 1, scheduling_algorithm: ROUND_ROBIN, multi_process_service: false
[2025-10-31 20:58:46.520] [278956] [HailoRT] [info] [device.cpp:49] [Device] OS Version: Linux 6.12.47+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.12.47-1+rpt1~bookworm (2025-09-16) aarch64
[2025-10-31 20:58:46.521] [278956] [HailoRT] [info] [control.cpp:108] [control__parse_identify_results] firmware_version is: 4.20.0
[2025-10-31 20:58:46.521] [278956] [HailoRT] [info] [vdevice.cpp:651] [create] VDevice Infos: 0001:01:00.0
[2025-10-31 20:58:46.543] [278956] [HailoRT] [info] [hef.cpp:1929] [get_network_group_and_network_name] No name was given. Addressing all networks of default network_group: yolov11l_inat
[2025-10-31 20:58:46.543] [278956] [HailoRT] [info] [hef.cpp:1929] [get_network_group_and_network_name] No name was given. Addressing all networks of default network_group: yolov11l_inat
[2025-10-31 20:58:46.554] [278956] [HailoRT] [info] [internal_buffer_manager.cpp:204] [print_execution_results] Planned internal buffer memory: CMA memory 0, user memory 8041984. memory to edge layer usage factor is 0.8673109
[2025-10-31 20:58:46.554] [278956] [HailoRT] [info] [internal_buffer_manager.cpp:212] [print_execution_results] Default Internal buffer planner executed successfully
[2025-10-31 20:58:46.590] [278956] [HailoRT] [info] [device_internal.cpp:57] [configure] Configuring HEF took 46.568392 milliseconds
[2025-10-31 20:58:46.590] [278956] [HailoRT] [info] [vdevice.cpp:749] [configure] Configuring HEF on VDevice took 46.890412 milliseconds
[2025-10-31 20:58:46.590] [278956] [HailoRT] [info] [infer_model.cpp:436] [configure] Configuring network group 'yolov11l_inat' with params: batch size: 0, power mode: PERFORMANCE, latency: NONE
[2025-10-31 20:58:46.590] [278956] [HailoRT] [info] [multi_io_elements.cpp:756] [create] Created (AsyncHwEl)
[2025-10-31 20:58:46.590] [278956] [HailoRT] [info] [queue_elements.cpp:450] [create] Created (EntryPushQEl0yolov11l_inat/input_layer1 | timeout: 10s)
[2025-10-31 20:58:46.590] [278956] [HailoRT] [info] [filter_elements.cpp:101] [create] Created (PreInferEl3yolov11l_inat/input_layer1 | Reorder - src_order: NHWC, src_shape: (640, 640, 3), dst_order: NHCW, dst_shape: (640, 640, 3))
[2025-10-31 20:58:46.590] [278956] [HailoRT] [info] [queue_elements.cpp:450] [create] Created (PushQEl3yolov11l_inat/input_layer1 | timeout: 10s)
[2025-10-31 20:58:46.590] [278956] [HailoRT] [info] [multi_io_elements.cpp:135] [create] Created (NmsPPMuxEl0YOLOV8-Post-Process | Op YOLOV8, Name: YOLOV8-Post-Process, Score threshold: 0.200, IoU threshold: 0.70, Classes: 198, Cross classes: false, NMS results order: BY_CLASS, Max bboxes per class: 100, Image height: 640, Image width: 640)
[2025-10-31 20:58:46.591] [278956] [HailoRT] [info] [queue_elements.cpp:942] [create] Created (MultiPushQEl0YOLOV8-Post-Process | timeout: 10s)
[2025-10-31 20:58:46.591] [278956] [HailoRT] [info] [edge_elements.cpp:187] [create] Created (LastAsyncEl0NmsPPMuxEl0YOLOV8-Post-Process)
[2025-10-31 20:58:46.591] [278956] [HailoRT] [info] [pipeline.cpp:891] [print_deep_description] EntryPushQEl0yolov11l_inat/input_layer1 | inputs: user | outputs: PreInferEl3yolov11l_inat/input_layer1(running in thread_id: 278975)
[2025-10-31 20:58:46.591] [278956] [HailoRT] [info] [pipeline.cpp:891] [print_deep_description] PreInferEl3yolov11l_inat/input_layer1 | inputs: EntryPushQEl0yolov11l_inat/input_layer1[0] | outputs: PushQEl3yolov11l_inat/input_layer1
[2025-10-31 20:58:46.591] [278956] [HailoRT] [info] [pipeline.cpp:891] [print_deep_description] PushQEl3yolov11l_inat/input_layer1 | inputs: PreInferEl3yolov11l_inat/input_layer1[0] | outputs: AsyncHwEl(running in thread_id: 278976)
[2025-10-31 20:58:46.591] [278956] [HailoRT] [info] [pipeline.cpp:891] [print_deep_description] AsyncHwEl | inputs: PushQEl3yolov11l_inat/input_layer1[0] | outputs: MultiPushQEl0YOLOV8-Post-Process MultiPushQEl0YOLOV8-Post-Process MultiPushQEl0YOLOV8-Post-Process MultiPushQEl0YOLOV8-Post-Pro

112
snap_version.py Normal file
View File

@@ -0,0 +1,112 @@
from common_code.settings import get_logger
from utils import run_model, start_snap_manager
import threading
import queue
import multiprocessing
import time
logger = get_logger('live_inference', file_path='/var/log/live_inference.log', stdout=True)
all_cameras_config = {
"camera_sidefeeder": {
'ip': "192.168.1.157",
'resolution': (360, 640, 3)
},
"camera_driveway": {
'ip': "192.168.1.152",
'resolution': (480, 640, 3)
},
"camera_railing": {
'ip': "192.168.1.153",
'resolution': (512, 896, 3)
},
"camera_ptz": {
'ip': "192.168.1.155",
'resolution': (360, 640, 3)
},
"camera_wrenwatch": {
'ip': "192.168.1.158",
'resolution': (360, 640, 3)
},
"camera_backyard": {
'ip': "192.168.1.162",
'resolution': (432, 1536, 3),
'split_into_two': True
},
}
for cam, details in all_cameras_config.items():
details['url_rtsp'] = f"rtsp://admin:marybear@{details['ip']}:554/h264Preview_01_sub"
details['url_api'] = f"http://{details['ip']}/cgi-bin/api.cgi"
details['username'] = 'admin'
details['password'] = 'marybear'
details['camera_name'] = cam
cameras_config = all_cameras_config
def start_system():
# Create shared multiprocessing queue for model
img_scoring_queue = multiprocessing.Queue(maxsize=len(cameras_config) * 2)
# Create threading queues for each camera
for cam, details in cameras_config.items():
details['msg_queue'] = queue.Queue(maxsize=1)
details['img_scoring_queue'] = img_scoring_queue
# Start model process
model_process = multiprocessing.Process(target=run_model, args=(img_scoring_queue,))
model_process.daemon = True
model_process.start()
logger.info('Started model process')
# Start camera threads
camera_threads = []
for cam_name, details in cameras_config.items():
thread = threading.Thread(target=start_snap_manager, kwargs=details)
thread.daemon = True
thread.start()
camera_threads.append(thread)
logger.info(f'Started camera thread for {cam_name}')
logger.info("System started. Available cameras:")
for cam_name in cameras_config.keys():
logger.info(f" - {cam_name}")
# Auto-capture loop - continuously send get messages when queues are empty
msg_counts = dict()
for cam_name in cameras_config:
msg_counts[cam_name] = 0
try:
while True:
for cam_name, details in cameras_config.items():
try:
if details['msg_queue'].empty():
details['msg_queue'].put('get', block=False)
msg_counts[cam_name]+=1
logger.debug(f"Auto-sent 'get' to {cam_name}")
except queue.Full:
pass # Queue full, skip
except Exception as e:
logger.error(f"Error auto-sending to {cam_name}: {e}")
time.sleep(0.1) # Small delay
except KeyboardInterrupt:
logger.info("Shutting down...")
# Send exit messages to all cameras
for details in cameras_config.values():
try:
details['msg_queue'].put('exit', block=False)
except:
pass
# Terminate model process
if model_process.is_alive():
model_process.terminate()
model_process.join(timeout=5)
if model_process.is_alive():
model_process.kill()
if __name__ == "__main__":
multiprocessing.set_start_method('spawn', force=True) # Ensure compatibility
start_system()

198
species_list Normal file
View File

@@ -0,0 +1,198 @@
Acanthis flammea
Accipiter cooperii
Accipiter striatus
Actitis macularius
Agelaius phoeniceus
Aix sponsa
Ambystoma laterale
Ambystoma maculatum
Ambystoma tigrinum
Anas crecca
Anas platyrhynchos
Anas platyrhynchos domesticus
Anas rubripes
Anaxyrus americanus
Anaxyrus americanus americanus
Anser anser
Anser anser domesticus
Antigone canadensis
Aramus guarauna
Archilochus colubris
Ardea alba
Ardea herodias
Asio flammeus
Aythya affinis
Aythya americana
Aythya collaris
Aythya marila
Aythya valisineria
Baeolophus bicolor
Blarina brevicauda
Bombycilla cedrorum
Branta canadensis
Branta hutchinsii
Bubo virginianus
Bucephala albeola
Bucephala clangula
Buteo jamaicensis
Buteo lagopus
Buteo platypterus
Butorides virescens
Calidris minutilla
Canis latrans
Cardellina canadensis
Cardellina pusilla
Cardinalis cardinalis
Castor canadensis
Cathartes aura
Catharus guttatus
Catharus minimus
Catharus ustulatus
Certhia americana
Chaetura pelagica
Charadrius vociferus
Coccyzus americanus
Coccyzus erythropthalmus
Colaptes auratus
Columba livia domestica
Contopus cooperi
Contopus virens
Corvus brachyrhynchos
Cyanocitta cristata
Cygnus buccinator
Cygnus olor
Didelphis virginiana
Dolichonyx oryzivorus
Dryocopus pileatus
Dumetella carolinensis
Empidonax minimus
Empidonax traillii
Eptesicus fuscus
Eremophila alpestris
Falco columbarius
Falco peregrinus
Felis catus
Fulica americana
Gavia immer
Gavia stellata
Geothlypis trichas
Glaucomys volans
Haemorhous mexicanus
Haliaeetus leucocephalus
Hirundo rustica
Histrionicus histrionicus
Hydroprogne caspia
Hyla versicolor
Hylocichla mustelina
Icterus cucullatus
Icterus galbula
Icterus spurius
Ictinia mississippiensis
Junco hyemalis
Larus delawarensis
Lithobates catesbeianus
Lithobates clamitans
Lithobates pipiens
Lithobates sylvaticus
Lophodytes cucullatus
Marmota monax
Megaceryle alcyon
Megascops asio
Melanerpes carolinus
Melanerpes erythrocephalus
Meleagris gallopavo
Meleagris gallopavo silvestris
Melospiza georgiana
Melospiza lincolnii
Melospiza melodia
Mephitis mephitis
Mergus merganser
Mniotilta varia
Molothrus ater
Myiarchus crinitus
Notophthalmus viridescens
Nyctanassa violacea
Nycticorax nycticorax
Odocoileus virginianus
Ondatra zibethicus
Oreothlypis peregrina
Oreothlypis ruficapilla
Oxyura jamaicensis
Pandion haliaetus
Passer domesticus
Passerculus sandwichensis
Passerina cyanea
Petrochelidon pyrrhonota
Phasianus colchicus
Pheucticus ludovicianus
Picoides pubescens
Picoides villosus
Pipilo erythrophthalmus
Piranga olivacea
Piranga rubra
Plethodon cinereus
Podiceps auritus
Podilymbus podiceps
Poecile atricapillus
Polioptila caerulea
Procyon lotor
Procyon lotor lotor
Pseudacris crucifer
Quiscalus quiscula
Regulus calendula
Regulus satrapa
Sayornis phoebe
Scalopus aquaticus
Sciurus carolinensis
Sciurus niger
Scolopax minor
Seiurus aurocapilla
Setophaga americana
Setophaga caerulescens
Setophaga castanea
Setophaga coronata
Setophaga coronata coronata
Setophaga fusca
Setophaga magnolia
Setophaga palmarum
Setophaga pensylvanica
Setophaga petechia
Setophaga pinus
Setophaga ruticilla
Setophaga striata
Setophaga tigrina
Setophaga virens
Sialia sialis
Sitta canadensis
Sitta carolinensis
Sphyrapicus varius
Spinus pinus
Spinus tristis
Spizella passerina
Spizella pusilla
Spizelloides arborea
Stelgidopteryx serripennis
Strix varia
Sturnella magna
Sturnus vulgaris
Sylvilagus floridanus
Tachycineta bicolor
Tamias striatus
Tamiasciurus hudsonicus
Thryothorus ludovicianus
Toxostoma rufum
Tringa solitaria
Troglodytes aedon
Troglodytes hiemalis
Turdus migratorius
Tyrannus tyrannus
Vermivora chrysoptera
Vermivora cyanoptera
Vireo gilvus
Vireo olivaceus
Vireo philadelphicus
Vireo solitarius
Vulpes vulpes
Zenaida macroura
Zonotrichia albicollis
Zonotrichia leucophrys

11
test.py Normal file
View File

@@ -0,0 +1,11 @@
import time
import redis
r = redis.Redis('localhost',port=6379, db=14)
max_fail_age = 60*5,
proc_start_time = time.time()
# %%
redis_topic_ffmpeg_fail = 'camera_sidefeeder_sm_fail'
last_fails = [float(x) > max_fail_age for x in r.lrange(redis_topic_ffmpeg_fail, 0, -1) if float(x) > proc_start_time]

View File

@@ -30,14 +30,45 @@ import json
import redis import redis
import os import os
pfm = LogColorize.score_obj_det_embed pfm = LogColorize.score_obj_det_embed
# %%
with open('/home/thebears/source/infer/species_list','r') as sl: 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] species_list = [x for x in sl.read().split('\n') if len(x) > 0]
r = redis.Redis('localhost',port=6379, db=14) r = redis.Redis('localhost',port=6379, db=14)
logger = logging.getLogger('live_inference') logger = logging.getLogger('live_inference')
def get_snap( url, username, password, proxies = None, timeout=5, save_image = None, camera_name = 'N/A'):
data = {
'cmd': 'Snap',
'channel': 0,
'rs': ''.join(choices(string.ascii_uppercase + string.digits, k=10)),
'snapType':'sub',
'user': username,
'password': password,
}
parms = parse.urlencode(data, safe="!").encode("utf-8")
try:
response = requests.get(url, proxies=proxies, params=parms, timeout=timeout)
if response.status_code == 200:
rearr = np.frombuffer(bytearray(response.content), dtype=np.uint8)
img_bgr = cv2.imdecode(rearr,cv2.IMREAD_COLOR)
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
if save_image is not None:
os.makedirs(os.path.dirname(save_image), exist_ok=True)
cv2.imwrite( save_image, img_bgr)
logging.info(f'{camera_name}: Wrote image to {save_image}')
logging.info(f'{camera_name}: Got image of {img_rgb.shape}')
return img_rgb
except Exception as e:
logging.error(f'{camera_name} failure: {str(e)}')
raise
# %%
def resize_image(img_in, reshape_to_final=False): def resize_image(img_in, reshape_to_final=False):
if not isinstance(img_in, np.ndarray): if not isinstance(img_in, np.ndarray):
img_in = np.asarray(img_in) img_in = np.asarray(img_in)
@@ -153,7 +184,7 @@ class SnapManager():
self.password = password self.password = password
self.camera_name = camera_name self.camera_name = camera_name
self.split_into_two = split_into_two self.split_into_two = split_into_two
n self.msg_queue = msg_queue self.msg_queue = msg_queue
self.img_scoring_queue = img_scoring_queue self.img_scoring_queue = img_scoring_queue
logger.info(f"{self.camera_name}: initialized") logger.info(f"{self.camera_name}: initialized")
@@ -187,21 +218,18 @@ n self.msg_queue = msg_queue
return msg return msg
def capture_and_prepare(self): def capture_and_prepare(self):
img = get_snap(self.username, self.password, self.url_api, self.camera_name) img = get_snap(self.url_api,self.username, self.password, camera_name = self.camera_name)
if img is not None: if img is not None:
timestamp = time.time() timestamp = time.time()
return self.format_image_for_model(img, timestamp) return self.format_image_for_model(img, timestamp)
return [] return []
def run_forever(self): def run_forever(self):
while True: while True:
try: try:
msg = self.msg_queue.get(timeout=0.1) msg = self.msg_queue.get(timeout=0.1)
if msg == 'exit': if msg == 'exit':
break break
if msg == 'save_image':
if msg == 'get': if msg == 'get':
logger.info(f'Processing capture for {self.camera_name}') logger.info(f'Processing capture for {self.camera_name}')
model_msgs = self.capture_and_prepare() model_msgs = self.capture_and_prepare()