前一段是单独巡线,后一段是模板识别加巡线,只能识别寻不了线,求求大佬帮忙看一下
M
mvea 发布的帖子
-
RE: 尝试同时实现,无法巡线,下面前一段是单独巡线的,是正常的,后一段巡线加模板识别,不行
-
尝试同时实现,无法巡线,下面前一段是单独巡线的,是正常的,后一段巡线加模板识别,不行
# Untitled - By: 26306 - Fri May 23 2025 import sensor import time import image from pyb import UART uart = UART(3,115200) sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QQQVGA)#图像缩小,线性回归算法要求,降低时间 sensor.skip_frames(time=500) clock = time.clock() THRESHOLD =(0,20,-10,10,-10,10)#黑色线的阈值 last_error_bottom = 0#增加给底部坐标和倾斜角度积分和微分的全局变量 integral_bottom = 0 last_error_theta = 0#增加给底部坐标和倾斜角度积分和微分的全局变量 integral_theta = 0 def pid_control(error,last_error,integral,Kp,Ki,Kd): proportional = Kp * error integral += error#积分,刷新率高,加法就是积分 integral = integral * Ki derivative = Kd * (error - last_error) output = proportional + integral + derivative last_error = error return output, last_error,integral def get_endpoint(line): (x1,y1,x2,y2) = line.line()#直线的上下两个端点,底部y值大 if y1>y2: return (x1,y1) else : return (x2,y2)#那么下一步查找直线倾斜角度 def theta_change(theta): if theta > 90: theta = theta -180 return theta else : return theta while True: clock.tick() img = sensor.snapshot() img.binary([THRESHOLD])#二值化 img.open(1)#消除噪点 img.gaussian(1)#边缘光滑,下面就可以计算了 line = img.get_regression([(100,100)],robust = True) #下面判断是否真的找到直线 if line and line.magnitude() >8:#直线的置信度, img.draw_line(line.line(),color = (255,0,0), thickness = 2) bottom_x,bottom_y = get_endpoint(line) error_x = bottom_x-img.width()//2 #变量为直线的底部端点和画布中心的误差 theta = theta_change(line.theta())# error_x和 theta>0都是小车要往右走 output_bottom,last_error_bottom,integral_bottom = pid_control(error_x,last_error_bottom,integral_bottom,0.7,0,0.17) output_theta,last_error_theta,integral_theta = pid_control(theta,last_error_theta,integral_theta,0.8,0,0.2) output = output_bottom + output_theta if(output >100): output = 100 elif(output<-100): output=-100 output = int(output)#强制类型转化 send_value = 128 + output print("Send Value:", send_value) # 输出十进制值 result = "@%03d#" % send_value # 用 %03d 格式化,保证三位数 uart.write(result) else : result = "@%03d#" %0 uart.write(result) print("Send Value:", result) # 输出十进制值 #print(clock.fps()) #########以上是单独巡线的代码,是正常的,下面是巡线和模板结合的代码,无法巡线了 # OpenMV 多功能视觉处理 - 模板匹配 + PID巡线 # By: 26306 # Date: 2025-05-23 import sensor, image, time, math from image import SEARCH_EX, SEARCH_DS from pyb import LED, UART # 初始化UART uart = UART(3, 115200) # 初始化摄像头 sensor.reset() sensor.set_contrast(1) sensor.set_gainceiling(16) sensor.set_framesize(sensor.QQVGA) # 80x60分辨率 sensor.set_pixformat(sensor.GRAYSCALE) # 灰度图模式 sensor.skip_frames(time=500) # 等待设置生效 # 加载模板图像 template2 = image.Image("4.pgm") # PID控制参数 THRESHOLD = (0, 20, -10, 10, -10, 10) # 黑色线的阈值 last_error_bottom = 0 integral_bottom = 0 last_error_theta = 0 integral_theta = 0 clock = time.clock() def get_endpoint(line): """获取直线的底部端点""" (x1, y1, x2, y2) = line.line() return (x1, y1) if y1 > y2 else (x2, y2) def theta_change(theta): """角度归一化到[-90,90]""" return theta - 180 if theta > 90 else theta def pid_control(error, last_error, integral, Kp, Ki, Kd): """PID控制器""" proportional = Kp * error integral += error integral *= Ki derivative = Kd * (error - last_error) output = proportional + integral + derivative return output, error, integral while True: clock.tick() img = sensor.snapshot() # 获取原始图像 # ========== 1. 模板匹配部分 ========== r = img.find_template(template2, 0.70, step=4, search=SEARCH_EX) if r: print("A") img.draw_rectangle(r) # ========== 2. 巡线部分 ========== img2 = img.copy() # 创建独立副本用于巡线处理 img2.binary([THRESHOLD]) # 二值化 img2.open(1) # 开运算去噪 img2.gaussian(1) # 高斯滤波 line = img2.get_regression([(100, 100)], robust=True) if line and line.magnitude() > 8: # 绘制检测到的线 img.draw_line(line.line(), color=(255, 0, 0), thickness=2) # 计算控制参数 bottom_x, bottom_y = get_endpoint(line) error_x = bottom_x - img.width() // 2 theta = theta_change(line.theta()) # PID计算 output_bottom, last_error_bottom, integral_bottom = pid_control( error_x, last_error_bottom, integral_bottom, 0.7, 0, 0.17) output_theta, last_error_theta, integral_theta = pid_control( theta, last_error_theta, integral_theta, 0.8, 0, 0.2) # 综合输出 output = output_bottom + output_theta output = max(-100, min(100, output)) # 限制在[-100,100]范围 output = int(output) # 串口发送控制指令 send_value = 128 + output # 转换为128±100的范围 print("Send Value:", send_value) result = "@%03d#" % send_value # 格式化输出 uart.write(result) else: # 未检测到线时发送中性值 result = "@128#" uart.write(result) print("No line detected") # 显示帧率(调试用) # print(clock.fps())