求助大佬,为了做21年送药小车电赛题我写了个循迹的代码又在在线平台上训练了个数字识别的模型,这两份代码单独运行都好好的,但是怎么弄都不能把这两份代码合在一个程序里面运行,怎么改都有报错,ai也问了,弄了好久好久,求解答
from media.sensor import * # 导入sensor模块,使用摄像头相关接口
from media.display import * # 导入display模块,使用display相关接口
from media.media import * # 导入media模块,使用media相关接口
from machine import UART, FPIOA, Pin
import time
# FPIOA 和 UART 初始化
fpioa = FPIOA()
fpioa.set_function(11, FPIOA.UART2_TXD)
fpioa.set_function(12, FPIOA.UART2_RXD)
fpioa.set_function(53, FPIOA.GPIO53)
KEY = Pin(53, Pin.IN, Pin.PULL_DOWN)
uart = UART(UART.UART2, baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)
# 红色检测阈值
thresholds = [(23, 57, 30, 127, -128, 127)]
# 摄像头与显示初始化
sensor = Sensor(width=1280, height=720)
sensor.reset()
sensor.set_framesize(width=800, height=480)
sensor.set_pixformat(Sensor.RGB565)
Display.init(Display.ST7701, to_ide=True)
MediaManager.init()
sensor.run()
# 中间三条 ROI (权重)
ROIS1 = [
(225, 0, 400, 160, 0.3),
(225, 160, 400, 160, 0.35),
(225, 320, 400, 160, 0.35),
]
# 左右检测 ROI
ROIS2 = [
(0, 150, 250, 300), # 左
(550, 150, 250, 300), # 右
]
# 状态变量
key_flag = 0
flag = 0
turn_flag = 0
move_record = [] # 拐弯记录
return_mode = False # 去程/回程模式
current_index = 0
cross_detected = False # 上一帧是否检测到十字
num = 1 # 模拟外部识别(1=左转, 2=右转, else 直行)
# 计算红线偏差函数
def calculate_error(blobs, rois):
global flag, turn_flag
detected_any = False
weight_sum = 0
centroid_sum = 0
for i, roi in enumerate(rois):
if blobs[i]:
detected_any = True
largest = max(blobs[i], key=lambda b: b.pixels())
img.draw_rectangle(largest.x(), largest.y(), largest.w(), largest.h(), (0,0,255))
centroid_sum += largest.cx() * roi[4]
weight_sum += roi[4]
flag = 1 if detected_any else 0
if weight_sum:
center_x = centroid_sum/weight_sum
dx = center_x - 400
if dx > 0:
turn_flag = 1
else:
dx = -dx
turn_flag = 2
return dx
return 0
def filter_blob(blob):
# 忽略面积小或位于特定位置的 blob
if blob.pixels() < 2000:
return False
if 140 < blob.cx() < 160 and 240 < blob.cy() < 260:
return False
if 640 < blob.cx() < 660 and 240 < blob.cy() < 260:
return False
return True
while True:
img = sensor.snapshot()
# 中间 ROI 检测
mid_blobs = [img.find_blobs(thresholds, roi=roi[:4], merge=True) for roi in ROIS1]
delta_pos_x = int(calculate_error(mid_blobs, ROIS1))
# 按键切换模式
if KEY.value() == 1:
if flag == 0:
return_mode = True
current_index = len(move_record)-1
print("切换到回程模式")
else:
return_mode = False
move_record.clear()
print("切换到正常模式")
key_flag = 1 - key_flag
time.sleep_ms(300)
# 画出所有 ROI 框
for r in ROIS1 + ROIS2:
img.draw_rectangle(r[0], r[1], r[2], r[3], (255,0,0))
if key_flag:
img.draw_string(0,0, 'RUNNING', color=(255,0,0), scale=5)
# 1. 检测左右色块
left = img.find_blobs(thresholds, roi=ROIS2[0], merge=True)
right = img.find_blobs(thresholds, roi=ROIS2[1], merge=True)
# 2. 过滤不合格的 blob
left = [b for b in left if filter_blob(b)]
right = [b for b in right if filter_blob(b)]
# 3. 可视化与调试输出
if left:
lb = max(left, key=lambda b: b.pixels())
img.draw_rectangle(lb.x(), lb.y(), lb.w(), lb.h(), (255,0,0))
print(f"✔ 左红块:cx={lb.cx()}, cy={lb.cy()}, area={lb.pixels()}")
else:
print("✘ 左红块未检测到")
if right:
rb = max(right, key=lambda b: b.pixels())
img.draw_rectangle(rb.x(), rb.y(), rb.w(), rb.h(), (255,0,0))
print(f"✔ 右红块:cx={rb.cx()}, cy={rb.cy()}, area={rb.pixels()}")
else:
print("✘ 右红块未检测到")
is_cross = bool(left and right)
# 自动进入回程
if flag==0 and not return_mode:
return_mode = True
current_index = len(move_record)-1
print("自动切换到回程模式")
# 模拟外部动作
move_prepare = 1 if num==1 else (3 if num==2 else 2)
# 十字边沿检测
# 只在首次进入十字时记录路径(去程)
if is_cross and not cross_detected:
print("检测到十字边沿,记录动作")
if not return_mode:
if move_prepare == 1:
move_record.append(1) # 左
elif move_prepare == 3:
move_record.append(3) # 右
else:
move_record.append(2) # 直行
print("记录动作:", move_record)
else:
if current_index >= 0:
print(f"回程:准备执行动作 {move_record[current_index]}")
# 注意这里只记录,不执行转弯
# 只要当前帧处于十字,就执行转弯(持续输出)
if is_cross:
if not return_mode:
if move_prepare == 1:
delta_pos_x = 400
turn_flag = 2 # 左转
elif move_prepare == 3:
delta_pos_x = 400
turn_flag = 1 # 右转
else:
delta_pos_x = 0
turn_flag = 0 # 直行
else:
if current_index >= 0:
m = move_record[current_index]
if m == 1:
delta_pos_x = 410
turn_flag = 1 # 左转
elif m == 3:
delta_pos_x = 400
turn_flag = 2 # 右转
else:
delta_pos_x = 0
turn_flag = 0 # 直行
# 状态更新放在最后
cross_detected = is_cross
# 串口输出
print(f"[DEBUG] dx={delta_pos_x}, flag={flag}, turn_flag={turn_flag}, 记录路径={move_record}")
uart.write(f"S:{num},{delta_pos_x},{flag},{turn_flag}\n".encode())
Display.show_image(img)
以上是循迹部分的代码
import os, gc
from libs.PlatTasks import DetectionApp
from libs.PipeLine import PipeLine
from libs.Utils import *
# Set display mode: options are 'hdmi', 'lcd', 'lt9611', 'st7701', 'hx8399'
# 'hdmi' defaults to 'lt9611' (1920x1080); 'lcd' defaults to 'st7701' (800x480)
display_mode = "lcd"
# Define the input size for the RGB888P video frames
rgb888p_size = [1280, 720]
# Set root directory path for model and config
root_path = "/sdcard/mp_deployment_source/"
# Load deployment configuration
deploy_conf = read_json(root_path + "/deploy_config.json")
kmodel_path = root_path + deploy_conf["kmodel_path"] # KModel path
labels = deploy_conf["categories"] # Label list
confidence_threshold = deploy_conf["confidence_threshold"] # Confidence threshold
nms_threshold = deploy_conf["nms_threshold"] # NMS threshold
model_input_size = deploy_conf["img_size"] # Model input size
nms_option = deploy_conf["nms_option"] # NMS strategy
model_type = deploy_conf["model_type"] # Detection model type
anchors = []
if model_type == "AnchorBaseDet":
anchors = deploy_conf["anchors"][0] + deploy_conf["anchors"][1] + deploy_conf["anchors"][2]
# Inference configuration
inference_mode = "video" # Inference mode: 'video'
debug_mode = 0 # Debug mode flag
# Create and initialize the video/display pipeline
pl = PipeLine(rgb888p_size=rgb888p_size, display_mode=display_mode)
pl.create()
display_size = pl.get_display_size()
# Initialize object detection application
det_app = DetectionApp(inference_mode,kmodel_path,labels,model_input_size,anchors,model_type,confidence_threshold,nms_threshold,rgb888p_size,display_size,debug_mode=debug_mode)
# Configure preprocessing for the model
det_app.config_preprocess()
# Main loop: capture, run inference, display results
while True:
with ScopedTiming("total", 1):
img = pl.get_frame() # Capture current frame
res = det_app.run(img) # Run inference
det_app.draw_result(pl.osd_img, res) # Draw detection results
pl.show_image() # Show result on display
gc.collect() # Run garbage collection
# Cleanup: These lines will only run if the loop is interrupted (e.g., by an IDE break or external interruption)
det_app.deinit() # De-initialize detection app
pl.destroy() # Destroy pipeline instance
以上就是训练平台给的代码
from media.sensor import * # 导入sensor模块,使用摄像头相关接口
from media.display import * # 导入display模块,使用display相关接口
from media.media import * # 导入media模块,使用media相关接口
from libs.PlatTasks import DetectionApp
from libs.PipeLine import PipeLine
from libs.Utils import *
from machine import UART, FPIOA, Pin
import time
import os, gc
# 定义 RGB888P 视频帧的输入尺寸
rgb888p_size = [1280, 720]
# 设置模型和配置文件的根目录路径
root_path = "/sdcard/mp_deployment_source/"
# 加载部署配置
deploy_conf = read_json(root_path + "/deploy_config.json")
kmodel_path = root_path + deploy_conf["kmodel_path"] # KModel 文件路径
labels = deploy_conf["categories"] # 标签列表
confidence_threshold = deploy_conf["confidence_threshold"] # 置信度阈值
nms_threshold = deploy_conf["nms_threshold"] # 非极大值抑制阈值
model_input_size = deploy_conf["img_size"] # 模型输入尺寸
nms_option = deploy_conf["nms_option"] # NMS 策略
model_type = deploy_conf["model_type"] # 检测模型类型
anchors = []
if model_type == "AnchorBaseDet":
anchors = deploy_conf["anchors"][0] + deploy_conf["anchors"][1] + deploy_conf["anchors"][2]
# 推理配置
inference_mode = "video" # 推理模式:'video'
debug_mode = 0 # 调试模式标志
# 创建并初始化视频/显示流水线
display_mode = "lcd"
pl = PipeLine(rgb888p_size=rgb888p_size, display_mode=display_mode)
pl.create()
display_size = pl.get_display_size()
# 初始化目标检测应用
det_app = DetectionApp(inference_mode, kmodel_path, labels, model_input_size, anchors, model_type, confidence_threshold, nms_threshold, rgb888p_size, display_size, debug_mode=debug_mode)
# 配置模型的预处理参数
det_app.config_preprocess()
# FPIOA 和 UART 初始化
fpioa = FPIOA()
fpioa.set_function(11, FPIOA.UART2_TXD)
fpioa.set_function(12, FPIOA.UART2_RXD)
fpioa.set_function(53, FPIOA.GPIO53)
KEY = Pin(53, Pin.IN, Pin.PULL_DOWN)
uart = UART(UART.UART2, baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)
# 红色检测阈值
thresholds = [(23, 57, 30, 127, -128, 127)]
# 摄像头与显示初始化(避免重复初始化,使用标准分辨率常量)
sensor = Sensor() # 直接初始化,避免传参导致重复初始化错误
sensor.reset()
sensor.set_framesize(sensor.QVGA) # 320x240,摄像头支持的标准分辨率,可改为 VGA、QVGA 等
sensor.set_pixformat(Sensor.RGB565)
sensor.run()
Display.init(Display.ST7701, to_ide=True)
MediaManager.init()
# 中间三条 ROI (权重)
ROIS1 = [
(225, 0, 400, 160, 0.3),
(225, 160, 400, 160, 0.35),
(225, 320, 400, 160, 0.35),
]
# 左右检测 ROI
ROIS2 = [
(0, 150, 250, 300), # 左
(550, 150, 250, 300), # 右
]
# 状态变量
key_flag = 0
flag = 0
turn_flag = 0
move_record = [] # 拐弯记录
return_mode = False # 去程/回程模式
current_index = 0
cross_detected = False # 上一帧是否检测到十字
num = 1 # 模拟外部识别(1=左转, 2=右转, else 直行)
# 计算红线偏差函数
def calculate_error(blobs, rois):
global flag, turn_flag
detected_any = False
weight_sum = 0
centroid_sum = 0
for i, roi in enumerate(rois):
if blobs[i]:
detected_any = True
largest = max(blobs[i], key=lambda b: b.pixels())
img.draw_rectangle(largest.x(), largest.y(), largest.w(), largest.h(), (0,0,255))
centroid_sum += largest.cx() * roi[4]
weight_sum += roi[4]
flag = 1 if detected_any else 0
if weight_sum:
center_x = centroid_sum/weight_sum
dx = center_x - 400
if dx > 0:
turn_flag = 1
else:
dx = -dx
turn_flag = 2
return dx
return 0
def filter_blob(blob):
if blob.pixels() < 2000:
return False
if 140 < blob.cx() < 160 and 240 < blob.cy() < 260:
return False
if 640 < blob.cx() < 660 and 240 < blob.cy() < 260:
return False
return True
while True:
img = sensor.snapshot()
res = det_app.run(img)
# 处理目标检测结果
scores = res['scores']
idxs = res['idx']
boxes = res['boxes']
for i in range(len(idxs)):
class_id = idxs[i]
score = scores[i]
box = boxes[i]
name = labels[class_id]
print(f"检测到物品: {name}, 置信度: {score:.2f}, 位置: {box}")
# 中间 ROI 检测
mid_blobs = [img.find_blobs(thresholds, roi=roi[:4], merge=True) for roi in ROIS1]
delta_pos_x = int(calculate_error(mid_blobs, ROIS1))
# 按键切换模式
if KEY.value() == 1:
if flag == 0:
return_mode = True
current_index = len(move_record)-1
print("切换到回程模式")
else:
return_mode = False
move_record.clear()
print("切换到正常模式")
key_flag = 1 - key_flag
time.sleep_ms(300)
# 画出所有 ROI 框
for r in ROIS1 + ROIS2:
img.draw_rectangle(r[0], r[1], r[2], r[3], (255,0,0))
if key_flag:
img.draw_string(0,0, 'RUNNING', color=(255,0,0), scale=5)
# 1. 检测左右色块
left = img.find_blobs(thresholds, roi=ROIS2[0], merge=True)
right = img.find_blobs(thresholds, roi=ROIS2[1], merge=True)
# 2. 过滤不合格的 blob
left = [b for b in left if filter_blob(b)]
right = [b for b in right if filter_blob(b)]
# 3. 可视化与调试输出
if left:
lb = max(left, key=lambda b: b.pixels())
img.draw_rectangle(lb.x(), lb.y(), lb.w(), lb.h(), (255,0,0))
print(f"✔ 左红块:cx={lb.cx()}, cy={lb.cy()}, area={lb.pixels()}")
else:
print("✘ 左红块未检测到")
if right:
rb = max(right, key=lambda b: b.pixels())
img.draw_rectangle(rb.x(), rb.y(), rb.w(), rb.h(), (255,0,0))
print(f"✔ 右红块:cx={rb.cx()}, cy={rb.cy()}, area={rb.pixels()}")
else:
print("✘ 右红块未检测到")
is_cross = bool(left and right)
# 自动进入回程
if flag==0 and not return_mode:
return_mode = True
current_index = len(move_record)-1
print("自动切换到回程模式")
# 模拟外部动作
move_prepare = 1 if num==1 else (3 if num==2 else 2)
# 十字边沿检测
if is_cross and not cross_detected:
print("检测到十字边沿,记录动作")
if not return_mode:
if move_prepare == 1:
move_record.append(1) # 左
elif move_prepare == 3:
move_record.append(3) # 右
else:
move_record.append(2) # 直行
print("记录动作:", move_record)
else:
if current_index >= 0:
print(f"回程:准备执行动作 {move_record[current_index]}")
# 这里只记录,不执行转弯
# 只要当前帧处于十字,就执行转弯(持续输出)
if is_cross:
if not return_mode:
if move_prepare == 1:
delta_pos_x = 400
turn_flag = 2 # 左转
elif move_prepare == 3:
delta_pos_x = 400
turn_flag = 1 # 右转
else:
delta_pos_x = 0
turn_flag = 0 # 直行
else:
if current_index >= 0:
m = move_record[current_index]
if m == 1:
delta_pos_x = 410
turn_flag = 1 # 左转
elif m == 3:
delta_pos_x = 400
turn_flag = 2 # 右转
else:
delta_pos_x = 0
turn_flag = 0 # 直行
cross_detected = is_cross
# 串口输出
print(f"[DEBUG] dx={delta_pos_x}, flag={flag}, turn_flag={turn_flag}, 记录路径={move_record}")
uart.write(f"S:{num},{delta_pos_x},{flag},{turn_flag}\n".encode())
Display.show_image(img)
以上是我自己写的合在一起的版本但是这个报错我不知道该怎么改,求大佬解答,真的球球了
Traceback (most recent call last):
File "<stdin>", line 58, in <module>
File "media/sensor.py", line 1, in __init__
OSError: sensor(2) is already inited.
MPY: soft reboot
CanMV v1.2.2(based on Micropython e00a144) on 2025-06-16; k230_canmv_lckfb with K230