feat: 2.17.18
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
id: t11
|
||||
name: t11
|
||||
version: 2.17.15
|
||||
version: 2.17.18
|
||||
author: t11
|
||||
icon: ''
|
||||
desc: t11
|
||||
|
||||
+1
-26
@@ -8,15 +8,6 @@ import threading
|
||||
import config
|
||||
from logger_manager import logger_manager
|
||||
|
||||
_USE_CV = False
|
||||
try:
|
||||
import cv2
|
||||
import numpy as np
|
||||
from maix import image as _maix_image
|
||||
_USE_CV = True
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
class CameraManager:
|
||||
"""相机管理器(单例)"""
|
||||
@@ -110,23 +101,7 @@ class CameraManager:
|
||||
with self._camera_lock:
|
||||
if self._camera is None:
|
||||
self.init_camera()
|
||||
frame = self._camera.read()
|
||||
if frame is not None and _USE_CV:
|
||||
try:
|
||||
v_flip = getattr(config, 'CAMERA_V_FLIP', False)
|
||||
h_mirror = getattr(config, 'CAMERA_H_MIRROR', False)
|
||||
if v_flip or h_mirror:
|
||||
img_cv = _maix_image.image2cv(frame, False, False)
|
||||
if v_flip and h_mirror:
|
||||
img_cv = cv2.flip(img_cv, -1)
|
||||
elif v_flip:
|
||||
img_cv = cv2.flip(img_cv, 0)
|
||||
elif h_mirror:
|
||||
img_cv = cv2.flip(img_cv, 1)
|
||||
frame = _maix_image.cv2image(img_cv, False, False)
|
||||
except Exception:
|
||||
pass
|
||||
return frame
|
||||
return self._camera.read()
|
||||
|
||||
def show(self, image):
|
||||
"""
|
||||
|
||||
@@ -15,8 +15,6 @@ LOCAL_FILENAME = APP_DIR + "/main_tmp.py"
|
||||
# 相机初始化分辨率(CameraManager / main.py 使用)
|
||||
CAMERA_WIDTH = 640
|
||||
CAMERA_HEIGHT = 480
|
||||
CAMERA_V_FLIP = True # 摄像头垂直翻转(上下颠倒时设为 True)
|
||||
CAMERA_H_MIRROR = True # 摄像头水平镜像(左右反了时设为 True)
|
||||
|
||||
# 三角形检测缩图比例:默认按相机最长边缩到 1/2(性能更稳;可按需调整)
|
||||
# 取值范围建议 (0.25 ~ 1.0];1.0 表示不缩图
|
||||
@@ -329,16 +327,16 @@ MAX_CMD_THREADS = 10 # 并发命令线程上限(防止服务器下
|
||||
|
||||
# ==================== 图像保存配置 ====================
|
||||
SAVE_IMAGE_ENABLED = True # 是否保存图像(True=保存,False=不保存)
|
||||
SAVE_IMAGE_ON_FAILURE = False # 检测失败时是否强制保存图像(供调试测试用)
|
||||
SAVE_IMAGE_ON_FAILURE = True # 检测失败时是否强制保存图像(供调试测试用)
|
||||
PHOTO_DIR = "/root/phot" # 照片存储目录
|
||||
MAX_IMAGES = 1000
|
||||
SAVE_RAW_IMAGE_ENABLED = True # 额外保存完整原始帧(不画框、不画点、不裁剪)
|
||||
SAVE_RAW_IMAGE_ENABLED = False # 额外保存完整原始帧(不画框、不画点、不裁剪)
|
||||
RAW_IMAGE_DIR = PHOTO_DIR + "/raw"
|
||||
RAW_IMAGE_MAX_IMAGES = MAX_IMAGES
|
||||
# Stage2 调试目录(默认 PHOTO_DIR/stage2_roi)内 JPEG 最多保留张数;None 表示与 MAX_IMAGES 相同
|
||||
TRIANGLE_BLACK_YOLO_STAGE2_ROI_MAX_IMAGES = None
|
||||
|
||||
SHOW_CAMERA_PHOTO_WHILE_SHOOTING = True # 是否在拍摄时显示摄像头图像(True=显示,False=不显示),建议在连着USB测试过程中打开
|
||||
SHOW_CAMERA_PHOTO_WHILE_SHOOTING = False # 是否在拍摄时显示摄像头图像(True=显示,False=不显示),建议在连着USB测试过程中打开
|
||||
|
||||
# ==================== OTA配置 ====================
|
||||
MAX_BACKUPS = 5
|
||||
|
||||
@@ -385,11 +385,11 @@ def cmd_str():
|
||||
pressure_max = adc_val
|
||||
if len(pressure_buf) >= PRESSURE_BATCH_SIZE:
|
||||
_flush_pressure_buf("batch")
|
||||
# 突变增量检测:压力增量大于300时触发
|
||||
# 突变增量检测:压力增量大于400时触发
|
||||
# 触发后需等气压降到触发值以下才重新检测增量
|
||||
if adc_val < trigger_adc_val :
|
||||
enable_check = True
|
||||
if (adc_val - last_adc_val) > 500 and enable_check:
|
||||
if (adc_val - last_adc_val) > 200 and enable_check:
|
||||
hardware_manager.start_idle_timer() # 重新计时
|
||||
last_adc_trigger = current_time
|
||||
trigger_adc_val = adc_val # 记录触发时的气压值
|
||||
|
||||
+31
-7
@@ -59,6 +59,7 @@ def analyze_shot(frame, laser_point=None):
|
||||
"""
|
||||
logger = logger_manager.logger
|
||||
from datetime import datetime
|
||||
yellow_algorithm_ms = 0.0
|
||||
|
||||
# ── Step 1: 确定激光点 ────────────────────────────────────────────────────
|
||||
laser_point_method = None
|
||||
@@ -74,7 +75,11 @@ def analyze_shot(frame, laser_point=None):
|
||||
logger.info(f"[算法] 使用校准值: {laser_manager.laser_point}")
|
||||
else:
|
||||
# 动态模式:先做一次无激光点检测以估算距离,再推算激光点
|
||||
_, _, _, _, best_radius1_temp, _ = detect_circle_v3(frame, None)
|
||||
_t_yellow = time_std.perf_counter()
|
||||
try:
|
||||
_, _, _, _, best_radius1_temp, _ = detect_circle_v3(frame, None)
|
||||
finally:
|
||||
yellow_algorithm_ms += (time_std.perf_counter() - _t_yellow) * 1000.0
|
||||
distance_m_first = estimate_distance(best_radius1_temp) if best_radius1_temp else None
|
||||
if distance_m_first and distance_m_first > 0:
|
||||
laser_point = laser_manager.calculate_laser_point_from_distance(distance_m_first)
|
||||
@@ -119,6 +124,7 @@ def analyze_shot(frame, laser_point=None):
|
||||
"laser_point": laser_point, "laser_point_method": laser_point_method,
|
||||
"offset_method": "yellow_ellipse" if ellipse_params else "yellow_circle",
|
||||
"distance_method": "yellow_radius",
|
||||
"yellow_algorithm_ms": float(yellow_algorithm_ms),
|
||||
}
|
||||
if yolo_roi_xyxy is not None:
|
||||
out["yolo_roi_xyxy"] = yolo_roi_xyxy
|
||||
@@ -126,9 +132,12 @@ def analyze_shot(frame, laser_point=None):
|
||||
|
||||
if not use_tri:
|
||||
# 三角形未配置,直接跑圆形检测
|
||||
return _build_circle_result(
|
||||
detect_circle_v3(frame, laser_point, img_cv=img_cv)
|
||||
)
|
||||
_t_yellow = time_std.perf_counter()
|
||||
try:
|
||||
cdata = detect_circle_v3(frame, laser_point, img_cv=img_cv)
|
||||
finally:
|
||||
yellow_algorithm_ms += (time_std.perf_counter() - _t_yellow) * 1000.0
|
||||
return _build_circle_result(cdata)
|
||||
|
||||
# ── Step 4: 先独占跑三角形,超时或失败后再跑圆形(不与圆心并行,避免抢 CPU)──
|
||||
roi_xyxy = None
|
||||
@@ -281,6 +290,7 @@ def analyze_shot(frame, laser_point=None):
|
||||
"laser_point": laser_point, "laser_point_method": laser_point_method,
|
||||
"offset_method": tri.get("offset_method") or "triangle_homography",
|
||||
"distance_method": tri.get("distance_method") or "pnp_triangle",
|
||||
"yellow_algorithm_ms": float(yellow_algorithm_ms),
|
||||
"tri_markers": tri.get("markers", []),
|
||||
"tri_markers_completed": tri.get("markers_completed", []),
|
||||
"tri_homography": tri.get("homography"),
|
||||
@@ -301,7 +311,11 @@ def analyze_shot(frame, laser_point=None):
|
||||
|
||||
# 三角形超时或失败 → 跑圆心;圆心跑完后再检查三角形是否已结束
|
||||
try:
|
||||
cdata = detect_circle_v3(frame, laser_point, img_cv=img_cv)
|
||||
_t_yellow = time_std.perf_counter()
|
||||
try:
|
||||
cdata = detect_circle_v3(frame, laser_point, img_cv=img_cv)
|
||||
finally:
|
||||
yellow_algorithm_ms += (time_std.perf_counter() - _t_yellow) * 1000.0
|
||||
except Exception as e:
|
||||
logger.error(f"[CIRCLE] 圆形检测异常: {e}")
|
||||
cdata = (frame, None, None, None, None, None)
|
||||
@@ -337,10 +351,15 @@ def process_shot(adc_val):
|
||||
|
||||
# Classify only the current shot frame; never reuse a previous result.
|
||||
target_class_result = None
|
||||
yolo_target_ms = 0.0
|
||||
try:
|
||||
from target_roi_yolo import try_get_target_class_from_yolo
|
||||
|
||||
target_class_result = try_get_target_class_from_yolo(frame, logger=logger)
|
||||
_t_yolo_target = time_std.perf_counter()
|
||||
try:
|
||||
target_class_result = try_get_target_class_from_yolo(frame, logger=logger)
|
||||
finally:
|
||||
yolo_target_ms = (time_std.perf_counter() - _t_yolo_target) * 1000.0
|
||||
if logger:
|
||||
logger.info(f"[YOLO-TARGET] 当前箭业务结果: {target_class_result}")
|
||||
except Exception as exc:
|
||||
@@ -370,6 +389,7 @@ def process_shot(adc_val):
|
||||
laser_point_method = analysis_result["laser_point_method"]
|
||||
offset_method = analysis_result.get("offset_method", "yellow_circle")
|
||||
distance_method = analysis_result.get("distance_method", "yellow_radius")
|
||||
yellow_algorithm_ms = float(analysis_result.get("yellow_algorithm_ms", 0.0) or 0.0)
|
||||
tri_markers = analysis_result.get("tri_markers", [])
|
||||
tri_markers_completed = analysis_result.get("tri_markers_completed", [])
|
||||
tri_homography = analysis_result.get("tri_homography")
|
||||
@@ -419,7 +439,9 @@ def process_shot(adc_val):
|
||||
"r": 20.0, # 保留字段(服务端当前忽略,物理外环半径 cm)
|
||||
"target_class": target_label,
|
||||
"target_class_confidence": (
|
||||
float(target_confidence) if target_confidence is not None else None
|
||||
round(float(target_confidence), 2)
|
||||
if target_confidence is not None
|
||||
else None
|
||||
),
|
||||
"d": round((distance_m or 0.0) * 100),
|
||||
"d_laser": round((laser_distance_m or 0.0) * 100),
|
||||
@@ -431,6 +453,8 @@ def process_shot(adc_val):
|
||||
"target_y": float(y),
|
||||
"offset_method": offset_method,
|
||||
"distance_method": distance_method,
|
||||
"yellow_algorithm_ms": round(yellow_algorithm_ms, 2),
|
||||
"yolo_target_ms": round(float(yolo_target_ms), 2),
|
||||
}
|
||||
|
||||
if ellipse_params:
|
||||
|
||||
+1
-1
@@ -4,6 +4,6 @@
|
||||
应用版本号
|
||||
每次 OTA 更新时,只需要更新这个文件中的版本号
|
||||
"""
|
||||
VERSION = '2.17.15'
|
||||
VERSION = '2.17.18'
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user