完善V1.4踢乒乓球版本

This commit is contained in:
myperworld committed 2026-01-20 22:15:03 +08:00
1 parent d14fe6c37b
commit 72455a5e76
1864 files changed
+19290 -214

No files matched your search

+2
View File
@@ -65,3 +65,5 @@ servo 文件夹是用于写入舵机初始化程序
2025-12-26 v1.4增加建议云台人脸跟踪效果 2025-12-26 v1.4增加建议云台人脸跟踪效果
2026-01-01 v1.4实现机器人一起踢乒乓球功能,使用maixcam,离线运行。 2026-01-01 v1.4实现机器人一起踢乒乓球功能,使用maixcam,离线运行。
2026-01-20 v1.4 增加适配5.5g舵机方案。
Binary file not shown.
File renamed without changes.
@@ -4,7 +4,6 @@ from maix import uart, pinmap, time, err, gpio
from maix import app, nn from maix import app, nn
import traceback import traceback
from config import * from config import *
from test_face import *
from test_ball import * from test_ball import *
# ------------------------------ # ------------------------------
@@ -46,20 +45,6 @@ def init_system():
"img_width": img_width, "img_height": img_height, "image_center": image_center "img_width": img_width, "img_height": img_height, "image_center": image_center
} }
def callback(data: list[float], len: int):
global track_mode
# 2. 找到概率最大的关键词索引
max_prob = max(data) # 获取最大概率值
max_index = data.index(max_prob) # 获取最大概率对应的kw索引
# 3. 判断:仅当最大概率>0时,输出对应value
if max_prob > 0:
# 根据索引映射到kw_list的value(kw0→0,kw1→1,kw2→2)
output_value = [0, 1, 2][max_index]
print(f"识别结果:{output_value}") # 输出最终的value
track_mode = output_value
# ------------------------------ # ------------------------------
# 系统执行 # 系统执行
@@ -68,8 +53,10 @@ def callback(data: list[float], len: int):
try: try:
# 初始化系统资源 # 初始化系统资源
system_resources = init_system() system_resources = init_system()
update_led()
# 进入主循环 # 进入主循环
# trace_face_main(system_resources)
trace_ball_main(system_resources) trace_ball_main(system_resources)
except Exception as e: except Exception as e:
@@ -1,16 +1,29 @@
from maix import image, app, time from maix import image, app, time
# 橘黄色乒乓球的颜色阈值配置(HSV色域) # 橘黄色乒乓球的颜色阈值配置(HSV色域)
# yxl
thresholds = [ thresholds = [
[73, 93, 7, 27, 13, 33], [73, 93, 7, 27, 13, 33],
[40, 65, 30, 60, 40, 70], [40, 65, 30, 60, 40, 70],
[39, 59, 41, 61, 48, 68], [39, 59, 41, 61, 48, 68],
] ]
# 新增:丢失目标的阈值配置(可根据实际帧率调整,建议5-10帧) # mgw
LOST_FRAME_THRESHOLD = 10 # 连续x帧没识别到才判定为真正丢失 thresholds = [
SEND_INTERVAL = 5 # 控制指令发送间隔(避免高频发送,单位:ms) [60, 85, 10, 35, 60, 90],
[40, 65, 20, 50, 60, 90],
[30, 60, 30, 60, 40, 70],
]
# 丢失目标的阈值配置
LOST_FRAME_THRESHOLD = 20 # 连续x帧没识别到才判定为真正丢失
# 全局参数初始化
kick_status = ""
# ------------------------------
# 兵乓球追踪
# ------------------------------
def select_largest_blob(blobs): def select_largest_blob(blobs):
""" """
筛选并选取最大的有效blob(替换原融合逻辑) 筛选并选取最大的有效blob(替换原融合逻辑)
@@ -63,7 +76,12 @@ def calculate_deviation_ball(center, image_center):
else: else:
return None return None
def trace_ball_main(resources): def trace_ball_main(resources):
# 声明使用全局变量(两个参数都需要更新)
global kick_status
detector = resources["detector"] detector = resources["detector"]
cam = resources["cam"] cam = resources["cam"]
disp = resources["disp"] disp = resources["disp"]
@@ -72,14 +90,13 @@ def trace_ball_main(resources):
img_height = resources["img_height"] img_height = resources["img_height"]
image_center = resources["image_center"] image_center = resources["image_center"]
# 新增:状态变量初始化
last_valid_deviation = None # 记录最后一次有效偏移量 last_valid_deviation = None # 记录最后一次有效偏移量
lost_frames = 0 # 丢失帧数计数 lost_frames = 0 # 丢失帧数计数
last_send_time = 0 # 最后一次发送指令的时间(防高频)
while not app.need_exit(): while not app.need_exit():
current_time = time.ticks_ms()
img = cam.read().flip(image.FlipDir.Y) img = cam.read().flip(image.FlipDir.Y)
bcmd = ""
# 识别色块(像素阈值设为10,过滤小噪声) # 识别色块(像素阈值设为10,过滤小噪声)
blobs = img.find_blobs(thresholds, pixels_threshold=10) blobs = img.find_blobs(thresholds, pixels_threshold=10)
@@ -95,33 +112,18 @@ def trace_ball_main(resources):
# 1. 识别到有效目标:重置丢失计数,更新最后一次有效偏移 # 1. 识别到有效目标:重置丢失计数,更新最后一次有效偏移
lost_frames = 0 lost_frames = 0
last_valid_deviation = current_deviation last_valid_deviation = current_deviation
# 控制发送频率,避免串口堵塞 dx, dy = current_deviation
if current_time - last_send_time >= SEND_INTERVAL: bcmd = f"DX:{dx},DY:{dy};"
dx, dy = current_deviation
cmd = f"DX:{dx},DY:{dy};"
serial_dev.write_str(cmd)
print(f"识别到目标: {cmd}")
last_send_time = current_time
else: else:
# 2. 未识别到目标:累计丢失帧数 # 2. 未识别到目标:累计丢失帧数
lost_frames += 1 lost_frames += 1
if lost_frames < LOST_FRAME_THRESHOLD and last_valid_deviation is not None: if lost_frames < LOST_FRAME_THRESHOLD and last_valid_deviation is not None:
# 2.1 丢失帧数未达阈值:继续发送最后一次有效偏移 dx, dy = last_valid_deviation
if current_time - last_send_time >= SEND_INTERVAL: bcmd = f"DX:{dx},DY:{dy};"
dx, dy = last_valid_deviation
cmd = f"DX:{dx},DY:{dy};"
serial_dev.write_str(cmd)
print(f"短暂丢失,沿用最后偏移: {cmd} (丢失帧数: {lost_frames})")
last_send_time = current_time
else: else:
# 2.2 丢失帧数达阈值:发送9999,重置最后有效偏移 # 2.2 丢失帧数达阈值:发送9999,重置最后有效偏移
if current_time - last_send_time >= SEND_INTERVAL: bcmd = "DX:9999,DY:9999;"
cmd = f"DX:9999,DY:9999;" last_valid_deviation = None
serial_dev.write_str(cmd)
print(f"目标丢失超过阈值: {cmd} (丢失帧数: {lost_frames})")
last_valid_deviation = None
last_send_time = current_time
# -----------------------------------------------------------------
# 绘制识别结果 # 绘制识别结果
if largest_rect: if largest_rect:
@@ -130,5 +132,9 @@ def trace_ball_main(resources):
cx, cy = target_center cx, cy = target_center
img.draw_circle(cx, cy, 3, image.COLOR_RED, -1) img.draw_circle(cx, cy, 3, image.COLOR_RED, -1)
serial_dev.write_str(bcmd)
print(bcmd)
disp.show(img) disp.show(img)
time.sleep_ms(1) time.sleep_ms(1)
Loaded 100 of 1864 files, more files were not shown because too many files have changed in this diff. Show more