#三点法巡线
from maix import camera, display, image, time, app, uart, nn
import math
import struct
import serial_protocol
#detector = nn.YOLOv5(model = "/root/models/model-120311.maixcam/model_120311.mud")
#串口UART初始化
device = "/dev/ttyS0"
serial = uart.UART(device, 115200)
time.sleep_ms(100) # wait uart ready
comm_proto = serial_protocol.SerialProtocol()
data_buffer = bytearray()
#print
#摄像头初始化
cam = camera.Camera(320, 240) #灰度化
disp = display.Display()
#串口接收路线选择
receive_color = 2
receive_number = 0
Threshold_green=[[0, 80, -120, -10, 0, 30]] #绿色路线阈值
Threshold_black=[[0, 30, -10, 10, -10, 10]] #黑色路线阈值
# 左上角坐标点,宽,高,权值
ROIS=[(0,20,360,60,0.4), #上
(0,90,360,60,0.9), #中
(0,170,360,50,1.2)] #下
weight_sum = 0
for r in ROIS: weight_sum += r[4] #权重
line_rho= 0 #偏移量
last_line_rho = 0
#巡线
def car_run(img):
global line_rho, last_line_rho
line_rho = 0
line_blobs = []
centroid_sum = 0
weight_sum = 0
for r in ROIS:
max_blob_area = 0
max_blob = None
# 选择线路
if receive_color == 1:
blobs = img.find_blobs(Threshold_green, roi=r[0:4], merge=True, pixels_threshold=150)
elif receive_color == 2:
blobs = img.find_blobs(Threshold_black, roi=r[0:4], merge=True, pixels_threshold=150)
else:
return None
# 找最大色块
if blobs:
for b in blobs:
current_area = b.w() * b.h()
if current_area > max_blob_area:
max_blob_area = current_area
max_blob = b
if max_blob:
line_blobs.append(max_blob)
centroid_sum += max_blob.cx() * r[4]
weight_sum += r[4]
# 计算偏移量
if weight_sum != 0:
line_rho = int(centroid_sum / weight_sum)
last_line_rho = line_rho #更新上一次的rho值
else:
line_rho = last_line_rho
# 用于调试
img.draw_string(0, 30, f' rho= {line_rho}', image.COLOR_WHITE)
return line_blobs
#标记函数
def Mark(Line):
if Line:
for b in Line:
# 绘制最大色块的矩形
img.draw_rect(b.x(),b.y(),b.w(),b.h(),color=image.COLOR_WHITE)
# 显示十字标
img.draw_cross(b.cx(),b.cy(),image.Color.from_rgb(255, 255, 255), size=5, thickness=1)
# 显示最大色块的面积
img.draw_string(b.x(), b.y() - 10,
f"Area: {b.w() * b.h()}",
color=image.COLOR_YELLOW)
#发送数据
def Uart_Send(rho, digit_result):
# if(digit_result!=0):
data=struct.pack("<hh", rho, digit_result)
encoded = comm_proto.encode(data)
serial.write(encoded)
print(encoded)
#接收数据
def Uart_Receive():
global data_buffer
global receive_color,receive_number
length = serial.available()
if length > 0:
data = serial.read()
data_buffer += data
rc, bytes_redundant = comm_proto.is_valid(data_buffer)
if bytes_redundant > 0:
data_buffer = data_buffer[bytes_redundant:]
if rc >= 0:
result = comm_proto.decode(data_buffer)
if len(result) == 4:
packet_length = comm_proto.length(data_buffer)
data_buffer = data_buffer[packet_length:]
receive_color, receive_number = struct.unpack('<hh', result)
print(f'{receive_color},{receive_number},{result}')
return None
line_element=[]
# 数字识别函数
#def digit_run(img, target_number):
# target_number: 1,2,3,4
#label_map = {1: 'one', 2: 'two', 3: 'three', 4: 'four'}
#digit_result = 0
# if target_number not in label_map:
#return digit_result
# objs = detector.detect(img, conf_th=0.5, iou_th=0.45)
#for obj in objs:
# if detector.labels[obj.class_id] == label_map[target_number]:
# digit_result = target_number
# img.draw_rect(obj.x, obj.y, obj.w, obj.h, color=image.COLOR_RED)
#msg = f'{label_map[target_number]}: {obj.score:.2f}'
#img.draw_string(obj.x, obj.y, msg, color=image.COLOR_RED)
# return digit_result
while not app.need_exit():
t = time.time_ms()
img = cam.read()
# 数据接收
Uart_Receive()
color_result = 0
digit_result = 0
# 色块识别
if receive_color in (1, 2):
line_element = car_run(img)
Mark(line_element)
color_result = receive_color
else:
line_element = []
# 数字识别
if receive_number in (1, 2, 3, 4):
digit_result = digit_run(img, receive_number)
# 数据发送
Uart_Send(line_rho, digit_result)
# 屏幕显示
disp.show(img)
# print("FPS= ",int(1000 / (time.time_ms() - t)))
最新发布