完善V1.4踢乒乓球版本
This commit is contained in:
1 parent
d14fe6c37b
commit
72455a5e76
1864 files changed
+19290
-214
No files matched your search
@@ -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)
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 100 of 1864 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user