ajsutado salvamento para pós processamento
This commit is contained in:
parent
3b15a2473c
commit
405903d5da
|
|
@ -105,6 +105,11 @@ class CameraManager:
|
|||
self.perf = VisualPerfMonitor(janela=180)
|
||||
self.gpu_controller = None
|
||||
|
||||
self._ultimo_posproc_save_ts = 0.0
|
||||
self._posproc_save_lock = threading.Lock()
|
||||
self._posproc_salvando = False
|
||||
self.posproc_intervalo_min_s = 5.0
|
||||
|
||||
self._reset_runtime_state()
|
||||
|
||||
# ============================================================
|
||||
|
|
@ -197,6 +202,8 @@ class CameraManager:
|
|||
self.seg_config = load_seg_config()
|
||||
self.det_config = load_det_config()
|
||||
|
||||
self.posproc_intervalo_min_s = float(self.seg_config.get("posproc_intervalo_min_s", 5.0))
|
||||
|
||||
self.debug_visual = bool(self.seg_config.get("debug_visual", False))
|
||||
self.debug_perf = bool(self.seg_config.get("debug_perf", False))
|
||||
|
||||
|
|
@ -1252,6 +1259,8 @@ class CameraManager:
|
|||
if agora - self._ultimo_perf_publish >= 1.0:
|
||||
self._ultimo_perf_publish = agora
|
||||
|
||||
self._atualizar_config_dinamica_visual(intervalo_s=1.0)
|
||||
|
||||
ctrl = self.gpu_controller
|
||||
if ctrl is not None:
|
||||
ctrl.update_from_redis()
|
||||
|
|
@ -1291,6 +1300,33 @@ class CameraManager:
|
|||
except Exception as e:
|
||||
self.mostrar_log(f"[saude] erro: {e}")
|
||||
|
||||
def _atualizar_config_dinamica_visual(self, intervalo_s=1.0):
|
||||
agora = time.time()
|
||||
|
||||
if not hasattr(self, "_ultimo_config_update_ts"):
|
||||
self._ultimo_config_update_ts = 0.0
|
||||
|
||||
if (agora - self._ultimo_config_update_ts) < intervalo_s:
|
||||
return
|
||||
|
||||
try:
|
||||
from visual_worker.config import load_seg_config
|
||||
|
||||
cfg = load_seg_config() or {}
|
||||
self.seg_config = cfg
|
||||
|
||||
self.debug_visual = bool(cfg.get("debug_visual", self.debug_visual))
|
||||
self.debug_perf = bool(cfg.get("debug_perf", self.debug_perf))
|
||||
|
||||
self.posproc_intervalo_min_s = float(
|
||||
cfg.get("posproc_intervalo_min_s", self.posproc_intervalo_min_s)
|
||||
)
|
||||
|
||||
self._ultimo_config_update_ts = agora
|
||||
|
||||
except Exception as e:
|
||||
self.mostrar_log(f"[visual] erro ao atualizar config dinâmica: {e}")
|
||||
|
||||
def _verificar_desconexao_camera(self):
|
||||
if self.iniciando or self._em_warmup or time.time() < self._startup_grace_until:
|
||||
return
|
||||
|
|
@ -1441,7 +1477,6 @@ class CameraManager:
|
|||
frame_name = nome.strip() if nome else datetime.datetime.now().strftime("%Y%m%d_%H%M%S_%f")[:-3]
|
||||
|
||||
replay_jpeg_quality = 70
|
||||
pos_jpeg_quality = 100
|
||||
|
||||
for frame_type in tipos:
|
||||
try:
|
||||
|
|
@ -1463,13 +1498,48 @@ class CameraManager:
|
|||
# No Visual Worker, o dado científico é só a imagem limpa.
|
||||
# Salva com qualidade máxima.
|
||||
if tipo_enum == TipoFrameCamera.PosProcessamento:
|
||||
caminho = os.path.join(pasta, f"{nome_base}.png")
|
||||
pode_salvar, motivo = self._pode_salvar_posprocessamento()
|
||||
|
||||
ok = cv2.imwrite(caminho, frame)
|
||||
if not pode_salvar:
|
||||
self.mostrar_log(
|
||||
f"[visual][SAVE_PP] pulado | motivo={motivo} "
|
||||
f"intervalo_min={self.posproc_intervalo_min_s:.1f}s "
|
||||
f"nome={nome_base}"
|
||||
)
|
||||
continue
|
||||
|
||||
if ok:
|
||||
frames_salvos.append(caminho)
|
||||
frame_pp = frame.copy()
|
||||
|
||||
def salvar_pp_async(nome_base_async, pasta_async, frame_async):
|
||||
try:
|
||||
t_pp0 = time.perf_counter()
|
||||
|
||||
caminho = os.path.join(pasta_async, f"{nome_base_async}.png")
|
||||
|
||||
ok = cv2.imwrite(caminho, frame_async)
|
||||
|
||||
t_pp1 = time.perf_counter()
|
||||
|
||||
self.mostrar_log(
|
||||
f"[visual][SAVE_PP] salvo async | "
|
||||
f"nome={nome_base_async} "
|
||||
f"ok={ok} "
|
||||
f"tempo_ms={(t_pp1 - t_pp0) * 1000.0:.1f}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
self.mostrar_log(f"❌ Erro no visual SAVE_PP async: {e}")
|
||||
|
||||
finally:
|
||||
self._finalizar_salvamento_posprocessamento()
|
||||
|
||||
threading.Thread(
|
||||
target=salvar_pp_async,
|
||||
args=(nome_base, pasta, frame_pp),
|
||||
daemon=True
|
||||
).start()
|
||||
|
||||
frames_salvos.append(f"ASYNC_STARTED:{nome_base}")
|
||||
continue
|
||||
|
||||
# ====================================================
|
||||
|
|
@ -1493,6 +1563,26 @@ class CameraManager:
|
|||
self.mostrar_log(f"❌ Erro ao salvar frames visual: {e}")
|
||||
return []
|
||||
|
||||
def _pode_salvar_posprocessamento(self):
|
||||
agora = time.time()
|
||||
|
||||
with self._posproc_save_lock:
|
||||
if self._posproc_salvando:
|
||||
return False, "busy"
|
||||
|
||||
dt = agora - self._ultimo_posproc_save_ts
|
||||
if dt < self.posproc_intervalo_min_s:
|
||||
return False, f"cooldown_{dt:.2f}s"
|
||||
|
||||
self._posproc_salvando = True
|
||||
self._ultimo_posproc_save_ts = agora
|
||||
|
||||
return True, "ok"
|
||||
|
||||
def _finalizar_salvamento_posprocessamento(self):
|
||||
with self._posproc_save_lock:
|
||||
self._posproc_salvando = False
|
||||
|
||||
def _visual_disponivel_para_frame(self) -> bool:
|
||||
"""
|
||||
Indica se o Visual Worker tem o mínimo necessário para gerar/salvar frames.
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ VISUAL_DEFAULT_CONFIG = {
|
|||
# ============================================================
|
||||
# Mostra janelas OpenCV/debug visual. Não usar em runtime de campo.
|
||||
"debug_visual": False,
|
||||
"posproc_intervalo_min_s": 5.0,
|
||||
|
||||
# Publica logs de performance no console.
|
||||
"debug_perf": False,
|
||||
|
|
|
|||
|
|
@ -82,6 +82,11 @@ class CameraManager:
|
|||
|
||||
self.perf = VisualPerfMonitor(janela=180)
|
||||
|
||||
self._ultimo_posproc_save_ts = 0.0
|
||||
self._posproc_save_lock = threading.Lock()
|
||||
self._posproc_salvando = False
|
||||
self.posproc_intervalo_min_s = 5.0
|
||||
|
||||
self._reset_runtime_state()
|
||||
|
||||
# ============================================================
|
||||
|
|
@ -188,6 +193,8 @@ class CameraManager:
|
|||
from weed_worker.config import load_seg_config
|
||||
self.seg_config = load_seg_config()
|
||||
|
||||
self.posproc_intervalo_min_s = float(self.seg_config.get("posproc_intervalo_min_s", 5.0))
|
||||
|
||||
self._inicializar_camera(mx_id, self.seg_config)
|
||||
|
||||
if self.camera is None:
|
||||
|
|
@ -526,6 +533,7 @@ class CameraManager:
|
|||
cfg = load_seg_config()
|
||||
self.seg_config = cfg
|
||||
self.qtd_bicos = int(cfg.get("qtd_bicos", self.qtd_bicos or 7) or 7)
|
||||
self.posproc_intervalo_min_s = float(cfg.get("posproc_intervalo_min_s", self.posproc_intervalo_min_s))
|
||||
|
||||
if self.weed_detector is not None:
|
||||
self.weed_detector.atualizar_config(cfg)
|
||||
|
|
@ -1533,17 +1541,49 @@ class CameraManager:
|
|||
nome_frame = f"{frame_name}_{tipo_nome}"
|
||||
|
||||
if tipo_enum == TipoFrameCamera.PosProcessamento:
|
||||
caminhos = self._salvar_bruto_multiespectral(
|
||||
nome_base=nome_frame,
|
||||
pasta=pasta
|
||||
)
|
||||
pode_salvar, motivo = self._pode_salvar_posprocessamento()
|
||||
|
||||
if caminhos:
|
||||
if isinstance(caminhos, list):
|
||||
frames_salvos.extend(caminhos)
|
||||
else:
|
||||
frames_salvos.append(caminhos)
|
||||
if not pode_salvar:
|
||||
self.mostrar_log(
|
||||
f"[weed][SAVE_PP] pulado | motivo={motivo} "
|
||||
f"intervalo_min={self.posproc_intervalo_min_s:.1f}s "
|
||||
f"nome={nome_frame}"
|
||||
)
|
||||
continue
|
||||
|
||||
def salvar_pp_async(nome_frame_async, pasta_async):
|
||||
try:
|
||||
t_pp0 = time.perf_counter()
|
||||
|
||||
caminhos = self._salvar_bruto_multiespectral(
|
||||
nome_base=nome_frame_async,
|
||||
pasta=pasta_async
|
||||
)
|
||||
|
||||
t_pp1 = time.perf_counter()
|
||||
|
||||
qtd = len(caminhos) if isinstance(caminhos, list) else 1 if caminhos else 0
|
||||
|
||||
self.mostrar_log(
|
||||
f"[weed][SAVE_PP] salvo async | "
|
||||
f"nome={nome_frame_async} "
|
||||
f"arquivos={qtd} "
|
||||
f"tempo_ms={(t_pp1 - t_pp0) * 1000.0:.1f}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
self.mostrar_log(f"❌ Erro no SAVE_PP async: {e}")
|
||||
|
||||
finally:
|
||||
self._finalizar_salvamento_posprocessamento()
|
||||
|
||||
threading.Thread(
|
||||
target=salvar_pp_async,
|
||||
args=(nome_frame, pasta),
|
||||
daemon=True
|
||||
).start()
|
||||
|
||||
frames_salvos.append(f"{nome_frame}_PosProcessamento_ASYNC_STARTED")
|
||||
continue
|
||||
|
||||
# ====================================================
|
||||
|
|
@ -1635,3 +1675,24 @@ class CameraManager:
|
|||
except Exception as e:
|
||||
self.mostrar_log(f"❌ Erro ao salvar bruto multiespectral: {e}")
|
||||
return []
|
||||
|
||||
def _pode_salvar_posprocessamento(self):
|
||||
agora = time.time()
|
||||
|
||||
with self._posproc_save_lock:
|
||||
if self._posproc_salvando:
|
||||
return False, "busy"
|
||||
|
||||
dt = agora - self._ultimo_posproc_save_ts
|
||||
if dt < self.posproc_intervalo_min_s:
|
||||
return False, f"cooldown_{dt:.2f}s"
|
||||
|
||||
self._posproc_salvando = True
|
||||
self._ultimo_posproc_save_ts = agora
|
||||
|
||||
return True, "ok"
|
||||
|
||||
def _finalizar_salvamento_posprocessamento(self):
|
||||
with self._posproc_save_lock:
|
||||
self._posproc_salvando = False
|
||||
|
||||
|
|
@ -41,6 +41,7 @@ WEED_DEFAULT_CONFIG = {
|
|||
# ============================================================
|
||||
# Mostra janela OpenCV/debug visual. Não usar em runtime de campo.
|
||||
"debug_visual": False,
|
||||
"posproc_intervalo_min_s": 5.0,
|
||||
|
||||
# Publica logs de performance no console.
|
||||
"debug_perf": False,
|
||||
|
|
|
|||
Loading…
Reference in New Issue