拖了好久,终于有时间写写了
首先是edgeboard部署出现了问题,自己组网训练的图像识别模型一直推理失败。而改用目标检测模型后,又因为网络太复杂,仅仅组网加调参就花费了两个通宵,加上比赛时间紧张算力卡消耗太多模型训练时间不够等等问题,导致的结果就是模型效果比较差,实际推理时常常会出现数字8和数字6混淆的情况。
其次是涛爷的一番“神级”操作:一是报名表交成了另一队的,二是技术报告写的相当扯淡,既有图片显示方面的错误,同时由于我们的报告修改自实验室师哥前年电赛的模板,因此在智能小车的技术报告中,赫然出现了“发射体轨迹计算”这种东西(注:高亮的黄色和后面的错误也是自带的)
所谓“祸不单行”大概就是这样(
在距离封箱还剩1天半的时候,小车程序最终敲定了
因为F题分为3个任务,在不能加按键选择任务的情况下,我们选择了用延时加标记的方法确定当前任务执行到了哪一个。
显然延时这种开环的控制方法是很需要调参的,但我们时间实在有限因此参数调整的不是很到位,下位机与上位机的同步偏差较大,出现了几次上位机判断执行到任务3但下位机认为仍处于任务2的情况。
因为每次完成任务我们都会让小车原地差速旋转后正向驶回,这就导致在较快速度的旋转时摄像机不知道都看到了什么奇怪的东西,本来希望在小车返回时通过给镜头加盖的方式来减少此类干扰,结果发现再加镜头盖之后会出现Opencv崩溃的情况,目前这一问题的原因仍没有找到。
好在最后车及时搭完了,封箱之后听天由命
最终这次电赛的结果就是只完成了任务一,最终奖项是省二等奖,也算是本科生涯的遗憾了
虽然水平实在有限,但还是决定把自己写的部分代码发出来,请看到的dalao们轻喷(
########################
### AtomicD ###
########################
import numpy as np
from edgeboard import *
import sys
import serial
import time
from common import *
from capture import *
from display import *
from preprocess import *
import cv2
g_predictor = PaddleLitePredictor()
cnt = [0,0,0,0,0,0,0,0,0]
#STATE
STATE = {
'TIMES':0,#Times of task
'GET_SET':False, #If the target has setten or not
'GO_FIND':False, #Go to find the target before setten
'GOAL':0, #Target which need to find
'TIWCE':0,
'END':False, #End the Predict or not
}
#lower_hsv_num = np.array([25, 10, 15])
#upper_hsv_num = np.array([105, 170, 80])
class PredictResult(object):
"""result wrapper"""
def __init__(self, category, score, x, y, width, height):
"""init"""
self.type = int(category)
self.score = score
self.x = int(x)
self.y = int(y)
self.width = int(width)
self.height = int(height)
def predictorInit():
"""predictor config and initialization"""
global g_model_config
global g_system_config
global g_predictor
if g_model_config.is_combined_model:
g_predictor.set_model_file(g_model_config.model_file)
g_predictor.set_param_file(g_model_config.params_file)
else:
# TODO add not combined model load
pass
try:
g_predictor.load()
print("Predictor Init Success !!!")
return 0
except:
print("Error: CreatePaddlePredictor Failed.")
return -1
IS_FIRST_RUN = True
def predict(frame, timer):
"""predict with paddlelite and postprocess"""
origin_frame = frame.copy()
origin_h, origin_w, _ = origin_frame.shape
if not g_system_config.use_fpga_preprocess:
input_data = cpu_preprocess(frame, g_model_config)
g_predictor.set_input(input_data, 0)
else:
input_tensor = g_predictor.get_input(0)
fpga_preprocess(frame, input_tensor, g_model_config)
if g_model_config.is_yolo:
feed_shape = np.zeros((1, 2), dtype=np.int32)
feed_shape[0, 0] = origin_h
feed_shape[0, 1] = origin_w
shape_tensor = g_predictor.set_input(feed_shape, 1)
global IS_FIRST_RUN
if IS_FIRST_RUN:
IS_FIRST_RUN = False
g_predictor.run()
else:
timer.Continue()
g_predictor.run()
timer.Pause()
outputs = np.array(g_predictor.get_output(0))
#print(outputs)
res = list()
for data in outputs:
if len(data) <= 1:
break
#print(data)
#if data[1] > 1 or data[1] < 0:
# break
else:
score = data[1]
type_ = data[0]
#print(score)
#print(type_)
if score < g_model_config.threshold:
continue
if g_model_config.is_yolo:
data[4] = data[4] - data[2]
data[5] = data[5] - data[3]
res.append(PredictResult(*data))
else:
h, w, _ = origin_frame.shape
x = data[2] * w
y = data[3] * h
width = data[4]* w - x
height = data[5] * h - y
res.append(PredictResult(type_, score, x, y, width, height))
return res
#Judge the direction
def Truning_judge(r, com):
global cnt
global STATE
center_x = 320
frame_shape = frame.shape
r = boundaryCorrection(r, frame_shape[1], frame_shape[0])
if r.type >= 0 and r.type < len(g_model_config.labels):
bbx_x = (r.x + (r.width)/2)
print("bbx_x",bbx_x)
print("center_x",center_x)
if bbx_x<=center_x-5:
print("Trun Left")
#for i in range(5):
com.write("1".encode())
com.write("\n".encode())
#print(com.read_all())
elif bbx_x>center_x:
print("Trun right")
#0 1 2 3 4
#1 3 once detec
if STATE['TIMES']==1 or 3:
STATE['GO_FIND'] = False
STATE['GOAL'] = 0
#STATE['TIMES'] += 1
if STATE['TIMES']<5:
STATE['TIMES'] += 1
elif STATE['TIMES']>=5:
STATE['END'] = True
time.sleep(5)
print("over 1 3")
#2 4 twice detec
elif STATE['TIMES']==2 or 4:
print(STATE['TWICE'])
STATE['TWICE'] += 1
if STATE['TWICE'] == 2:
STATE['TWICE'] = 0
STATE['GO_FIND'] = False
STATE['GOAL'] = 0
#STATE['TIMES'] += 1
if STATE['TIMES']<5:
STATE['TIMES'] += 1
elif STATE['TIMES']>=5:
STATE['END'] = True
time.sleep(5)
print("over 2 4")
cnt = [0,0,0,0,0,0,0,0,0]
#predict the results
def printResults(frame, predict_result, com):
global cnt
global STATE
print(STATE)
for box_item in predict_result:
if len(g_model_config.labels)>0 and box_item.score>=0.85:
if STATE['GET_SET'] == False:
cnt[int(g_model_config.labels[box_item.type])] += 1
if STATE['TIMES'] == 0:#task 1
print("now task is task 1")
if cnt[int(g_model_config.labels[box_item.type])] >= 8:
STATE['GET_SET'] = True
STATE['GO_FIND'] = True
STATE['GOAL'] = int(g_model_config.labels[box_item.type])
print("GOAL HAS BEEN SETTEN :",STATE['GOAL'])
print(STATE)
print("*****START_JUDGE OF TASK 0*****")
if int(g_model_config.labels[box_item.type]) == 1:
print("Turn left")
#for i in range(10):
com.write("1".encode())
com.write("\n".encode())
#com.write("\n".encode())
print(com.read_all())
elif int(g_model_config.labels[box_item.type]) == 2:
print("Turn right")
cnt = [0,0,0,0,0,0,0,0,0,0]
STATE['TIMES'] += 1
STATE['GOAL'] = 0
STATE['GET_SET'] = False
STATE['GO_FIND'] = False
time.sleep(5)
break
else: #task 2,3,4,5
if int(g_model_config.labels[box_item.type])==1 or int(g_model_config.labels[box_item.type])==2:
continue
if cnt[int(g_model_config.labels[box_item.type])] >= 8:
STATE['GET_SET'] = True
STATE['GO_FIND'] = True
STATE['GOAL'] = int(g_model_config.labels[box_item.type])
cnt = [0,0,0,0,0,0,0,0,0]
time.sleep(5)
break
if STATE['GO_FIND'] == True and STATE['GO_FIND'] == True:
cnt[int(g_model_config.labels[box_item.type])] += 1
if cnt[STATE['GOAL']] >= 8:
Truning_judge(box_item, com)
break
#print("label: {}".format(g_model_config.labels[box_item.type]))
#str_ = "index: {}".format(box_item.type) + ", score: {}".format(box_item.score) \
# + ", loc: {}".format(box_item.x) + ", {}".format(box_item.y) + ", {}".format(box_item.width) \
# + ", {}".format(box_item.height)
#print(str_)
def boundaryCorrection(predict_result, width_range, height_range):
MARGIN_PIXELS = 2
predict_result.width = width_range - predict_result.x - MARGIN_PIXELS \
if predict_result.width > (width_range - predict_result.x - MARGIN_PIXELS) else predict_result.width
predict_result.height = height_range - predict_result.y - MARGIN_PIXELS \
if predict_result.height > (height_range - predict_result.y - MARGIN_PIXELS) else predict_result.height
predict_result.x = MARGIN_PIXELS if predict_result.x < MARGIN_PIXELS else predict_result.x
predict_result.y = MARGIN_PIXELS if predict_result.y < MARGIN_PIXELS else predict_result.y
return predict_result
def drawResults(frame, results):
frame_shape = frame.shape
for r in results:
r = boundaryCorrection(r, frame_shape[1], frame_shape[0])
if r.type >= 0 and r.type < len(g_model_config.labels) and r.score >= 0.85:
origin = (r.x, r.y)
label_name = g_model_config.labels[r.type]
cv2.putText(frame, label_name, origin, cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 224), 2)
cv2.rectangle(frame, (r.x, r.y), (r.x + r.width, r.y + r.height), (0, 0, 224), 2)
if __name__ == "__main__":
#cnt = [0,0,0,0,0,0,0,0,0]
try:
uartport = "/dev/ttyUSB0"
bps = 115200
bytesize = 8
timeout = 1
com_ = serial.Serial(uartport, bps, bytesize=bytesize, timeout=timeout, parity="N", stopbits=1, write_timeout=1)
#com_.close()
print("Success the port: ", uartport)
except Exception as e:
print("ERROR: Can not open this port",e)
if len(sys.argv) > 1:
system_config_path = sys.argv[1]
else:
system_config_path = "/root/PaddleLiteDemo/PaddleLiteDemo/configs/detection/mobilenet-ssd-640/usbserial.json"
print("SystemConfig Path: {}".format(system_config_path))
g_system_config = SystemConfig(system_config_path)
model_config_path = g_system_config.model_config_path
g_model_config = ModelConfig(model_config_path)
timer = Timer("Predict", 100)
capture = createCapture(g_system_config.input_type, g_system_config.input_path)
if capture is None:
exit(-1)
ret = predictorInit()
if ret != 0:
print("Error!!! predictor init failed .")
sys.exit(-1)
print("success")
while True:
#print("END: ",END)
if STATE['END'] == True:
break
frame = capture.getFrame()
origin_frame = frame.copy()
predict_result = predict(frame, timer)
#drawResults(origin_frame, predict_result)
if g_system_config.predict_log_enable:
#print("task_num is ",STATE['TIMES'])
if STATE['GOAL'] == 0:
STATE['GET_SET'] = False
printResults(origin_frame, predict_result, com_)
capture.stop()
com_.close()
总结问题这次比赛遇到的种种问题,归根结底还是准备不足
- 对PaddleLite不够熟悉
Paddlepaddle2.0推出之后太过于依赖动态图的编程方式,导致的结果就是在Edgeboard这种对动态图支持不太好的硬件上举步维艰,在比赛过程中又需要拿出相当长的时间去重新学习静态图的编程,严重压缩了后续编程与调参的时间 - 队伍内分工不够明确,对队友所擅长和不擅长的方面认识不足
- 前期对自己过于自信,浪费太多时间在模型效果测试上,反而浪费了模型部署的时间
- 对赛题的分析也不仔细,导致一些有可能成为突破点的想法,直到比赛之后才想起来还可以这么做(比如不识别数字而只是识别左右等等)
虽然现在的我已经跟电赛当时的我有所进步了,但自己水平还是太菜,以后还是要努力学习,巩固各方位的能力才行