v4
This commit is contained in:
@@ -9,23 +9,46 @@ import time
|
||||
|
||||
_CAMERA_LOCK = threading.Lock()
|
||||
|
||||
# DONA_VISION_V95 : partage une image récente avec la détection YOLOv8.
|
||||
_FRAME_LOCK = threading.Lock()
|
||||
_LAST_FRAME = None
|
||||
_FRAME_TIMESTAMP = 0.0
|
||||
|
||||
def _cache_frame(frame):
|
||||
global _LAST_FRAME, _FRAME_TIMESTAMP
|
||||
with _FRAME_LOCK:
|
||||
_LAST_FRAME = frame.copy()
|
||||
_FRAME_TIMESTAMP = time.monotonic()
|
||||
|
||||
def read_frame(index=None, max_age=1.4):
|
||||
"""Retourne une image de l'aperçu actif ou capture sans collision de caméra."""
|
||||
import cv2
|
||||
with _FRAME_LOCK:
|
||||
if _LAST_FRAME is not None and time.monotonic() - _FRAME_TIMESTAMP <= max_age:
|
||||
return _LAST_FRAME.copy()
|
||||
if not _CAMERA_LOCK.acquire(blocking=False):
|
||||
raise RuntimeError('Caméra occupée : active l’aperçu et réessaie, ou ferme l’autre application.')
|
||||
cap = None
|
||||
try:
|
||||
cam_index = int(os.getenv('CAMERA_INDEX', '0')) if index is None else index
|
||||
cap = cv2.VideoCapture(cam_index)
|
||||
if not cap.isOpened():
|
||||
raise RuntimeError('Caméra indisponible sur Dona.')
|
||||
ok, frame = cap.read()
|
||||
if not ok: raise RuntimeError('Capture caméra impossible.')
|
||||
_cache_frame(frame)
|
||||
return frame
|
||||
finally:
|
||||
if cap is not None: cap.release()
|
||||
_CAMERA_LOCK.release()
|
||||
|
||||
|
||||
|
||||
def snapshot(path, index=0):
|
||||
import cv2
|
||||
if not _CAMERA_LOCK.acquire(blocking=False):
|
||||
raise RuntimeError('Caméra déjà utilisée par la prévisualisation de ' + os.getenv('ALFRED_NAME', 'Alfred')) # ALFRED_IDENTITY_GLASS_V1
|
||||
try:
|
||||
cap = cv2.VideoCapture(index)
|
||||
try:
|
||||
ok, frame = cap.read()
|
||||
finally:
|
||||
cap.release()
|
||||
if not ok:
|
||||
raise RuntimeError('Impossible de lire la caméra locale')
|
||||
cv2.imwrite(path, frame)
|
||||
return path
|
||||
finally:
|
||||
_CAMERA_LOCK.release()
|
||||
frame = read_frame(index=index)
|
||||
if not cv2.imwrite(path,frame): raise RuntimeError('Impossible d’enregistrer la capture.')
|
||||
return path
|
||||
|
||||
|
||||
def video_stream(index=0):
|
||||
@@ -60,6 +83,7 @@ def video_stream(index=0):
|
||||
ok, frame = cap.read()
|
||||
if not ok:
|
||||
break
|
||||
_cache_frame(frame) # DONA_VISION_V95 : vidéo et YOLO partagent la capture.
|
||||
ok_jpeg, encoded = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, quality])
|
||||
if ok_jpeg:
|
||||
yield b'--frame\r\nContent-Type: image/jpeg\r\n\r\n' + encoded.tobytes() + b'\r\n'
|
||||
|
||||
Reference in New Issue
Block a user