2019 电子设计大赛 激光炮题目 写的程序
usart_all.h
usart_all.c
见 STM32超级通用串口程序(秘籍)camera.h
:
#ifndef __CAMERA_H
#define __CAMERA_H
#include "sys.h"
void CAMERA_Init(void);
void CAMERA_Send_Cmd(u8 cmd);
char CAMERA_Check_Ready(void);
char CAMERA_Get_GoalErro(u8* goalErro);
char CAMERA_Receive_Data(u8* data);
void CAMERA_ClearRX(void);
void CAMERA_Release(void);
#endif
camera.c
:
#include "camera.h"
#include "usart_all.h"
#include "hmi.h"
void CAMERA_Init(void) {
USART1_Init(115200);
}
//清空摄像头传给单片机的数据
void CAMERA_ClearRX(void) {
USART1_ClearRXBuf();
}
void CAMERA_Send_Cmd(u8 cmd) {
USART1_PutChar(cmd);
}
char CAMERA_Receive_Data(u8* data) {
return USART1_GetChar(data);
}
char CAMERA_Get_GoalErro(u8* goalErro) {
return USART1_GetLastChar(goalErro);
}
//解除摄像机
void CAMERA_Release() {
USART1_Disable();
}
# 自动RGB565颜色跟踪示例
#
# 这个例子展示了使用OpenMV的单色自动RGB565色彩跟踪。
# framesize=QVGA时分辨率较高能较好的追踪 像素尺寸:320x240
# framesize=QQVGA2时分辨率较低,几乎不能追踪 像素尺寸:128x160 lcd必须
import sensor, image, time
from pyb import UART
import lcd
uart = UART(3, 115200, timeout_char=10) # i使用给定波特率初始化
uart.init(115200, bits=8, parity=None, stop=1, timeout_char=10) # 使用给定参数初始化
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA) # special 320x240 lcd shield resolution.
#sensor.set_framesize(sensor.VGA) # special 640x480 lcd shield resolution.
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
clock = time.clock()
# sensor采集到图片的宽高
img_width = sensor.width()
img_height = sensor.height()
lcd_width = 128
lcd_height = 160
lcd_display_roi = ((img_width-lcd_width)//2, (img_height-lcd_height)//2, lcd_width, lcd_height);
lcd.init() # Initialize the lcd screen.
adjust_sample_success = 0 # 取样调整成功标志
adjust_roi_success = 0 # 追踪区域调整成功标志
####################
# 需要调参,img.get_histogram(roi=goal_rect) lab色图直方图取样的区域
# 务必保证取样区域严格在 导引标识红靶 中!!!!
##################
sample_width = 10
sample_height = 10
sample_cx = img_width//2
sample_cy = img_height//2-20
sample_rect = [sample_cx-(sample_width//2), sample_cy-(sample_height//2), sample_width, sample_height] # 50x50 center of QVGA.
goal_center = sample_rect[0]+sample_rect[2]//2
# 获取阈值
####################
# 需要调参
# goal_area:引导标志红靶区域面积
##################
goal_area = 100
threshold = [50, 50, 0, 0, 0, 0] # Middle L, A, B values.
def get_threshold():
for i in range(60):
img = sensor.snapshot()
hist = img.get_histogram(roi=sample_rect)# 获取直方图
lo = hist.get_percentile(0.01) # 获取1%范围的直方图的CDF(根据需要调整)!
hi = hist.get_percentile(0.99) # 获取1%范围的直方图的CDF(根据需要调整)!
# 平均百分位值。
threshold[0] = (threshold[0] + lo.l_value()) // 2
threshold[1] = (threshold[1] + hi.l_value()) // 2
threshold[2] = (threshold[2] + lo.a_value()) // 2
threshold[3] = (threshold[3] + hi.a_value()) // 2
threshold[4] = (threshold[4] + lo.b_value()) // 2
threshold[5] = (threshold[5] + hi.b_value()) // 2
for blob in img.find_blobs([threshold], pixels_threshold=goal_area, area_threshold=goal_area, merge=True, margin=10):
img.draw_rectangle(blob.rect())
img.draw_cross(blob.cx(), blob.cy())
# 绘制取样框,调整取样框位置,获取阈值
def adjust_sample():
global adjust_sample_success
global adjust_roi_success
global goal_center
mode = "change_position" # 默认模式为改变取样框位置
while(True):
img = sensor.snapshot()
img.draw_rectangle(sample_rect, color=(0,255,0)) # 绿色框为取样框
goal_center = sample_rect[0]+sample_rect[2]//2
img.draw_cross(sample_rect[0]+sample_rect[2]//2, sample_rect[1]+sample_rect[3]//2, color=(0,255,0)) # 绿色十字为取样中心
img_lcd_display = img.copy(roi=lcd_display_roi)
lcd.display(img_lcd_display)
mcu_control_cmd = uart.readchar() # 获取单片机传来的控制数据
if mcu_control_cmd == 0x1:
mode = "change_position" # 改变取样框位置
elif mcu_control_cmd == 0x2:
mode = "change_size" # 改变取样框大小
elif mcu_control_cmd == 0x11: # 按向上键
if(mode == "change_position"):
sample_rect[1] -= 1 # [1]:y 取样框定位点上移
elif(mode == "change_size"):
sample_rect[3] -= 1 # [3]:h 取样框下限上移
elif mcu_control_cmd == 0x12: # 按向下键
if(mode == "change_position"):
sample_rect[1] += 1 # [1]:y 取样框定位点下移
elif(mode == "change_size"):
sample_rect[3] += 1 # [3]:h 取样框下限下移
elif mcu_control_cmd == 0x13: # 按向左键
if(mode == "change_position"):
sample_rect[0] -= 1 # [0]:x 取样框定位点左移
elif(mode == "change_size"):
sample_rect[2] -= 1 # [2]:w 取样框右限左移
elif mcu_control_cmd == 0x14: # 按向左键
if(mode == "change_position"):
sample_rect[0] += 1 # [0]:x 取样框定位点右移
elif(mode == "change_size"):
sample_rect[2] += 1 # [2]:w 取样框右限右移
elif mcu_control_cmd == 0x15:
# 获取阈值
get_threshold()
adjust_sample_success = 1
print("Threshold set successful")
uart.writechar(0x55)
break
####################
# 需要调参,find_blobs()的区域
##################
roi_to_left = 0
roi_to_right = 0
roi_to_height = 60
roi_to_bottom = 110
ROI = [roi_to_left, roi_to_height, img_width-roi_to_left-roi_to_right, img_height-roi_to_height-roi_to_bottom]
# 显示追踪效果,调整追踪区域,达到正确且不遗漏追踪
def adjust_roi():
global adjust_sample_success
global adjust_roi_success
global ROI
while(True):
img = sensor.snapshot()
img.draw_rectangle(tuple(ROI)) #绘制追踪区域
blobs = img.find_blobs([threshold], roi=tuple(ROI), pixels_threshold=goal_area, area_threshold=goal_area, merge=True, margin=10)
for blob in blobs:
img.draw_rectangle(blob.rect(), color=(0,0,255)) # 蓝色框为追踪框
img.draw_cross(blob.cx(), blob.cy(), color=(0,255,0)) # 蓝色十字为追踪物体的中心
img_lcd_display = img.copy(roi=lcd_display_roi)
lcd.display(img_lcd_display)
mcu_control_cmd = uart.readchar() # 获取单片机传来的控制数据
if mcu_control_cmd == 0x15:
print("上次没发送成功")
uart.writechar(0x55)
if mcu_control_cmd == 0x21:
# 向上移动追踪区域上限
ROI[1] -= 3 # 追踪框y值--,整体上移
ROI[3] += 3 # 追踪框height值++,保持下限不变
elif mcu_control_cmd == 0x22:
# 向下移动追踪区域上限
ROI[1] += 3 # 追踪框y值++,整体下移
ROI[3] -= 3 # 追踪框height值--,保持下限不变
elif mcu_control_cmd == 0x23:
# 向上移动追踪区域下限
ROI[3] -= 3 # 追踪框height值--,下限上移
elif mcu_control_cmd == 0x24:
# 向下移动追踪区域下限
ROI[3] += 3 # 追踪框height值++,下限下移
elif mcu_control_cmd == 0x25:
# 阈值设置有问题,返回重新设置
adjust_sample_success = 0
print("Threshold need reset")
uart.writechar(0x77)
break
elif mcu_control_cmd == 0x26:
# 阈值设置成功,且追踪区域设置成功
adjust_roi_success = 1
print("ROI set successful")
uart.writechar(0x66)
break
while(adjust_roi_success == 0):
adjust_sample()
adjust_roi()
print("All setting finished! adjust_sample_success:"+str(adjust_sample_success)+" adjust_roi_success:"+str(adjust_roi_success))
while(True):
clock.tick()
img = sensor.snapshot()
delta = 20
threshold[0] = threshold[0]-delta if (threshold[0]-delta) > 0 else 0
threshold[1] = threshold[1]+delta if (threshold[1]+delta) < 100 else 100
blobs = img.find_blobs([threshold], roi=tuple(ROI), pixels_threshold=goal_area, area_threshold=goal_area, merge=True, margin=10)
if len(blobs) == 1:
#img.draw_rectangle(blobs[0].rect())
#img.draw_cross(blobs[0].cx(), blobs[0].cy())
#img.draw_rectangle(tuple(ROI))
#img_lcd_display = img.copy(roi=lcd_display_roi)
#lcd.display(img_lcd_display)
sendErro = -(blobs[0].cx() - goal_center)
if sendErro > 127:
sendErro = 127
elif sendErro < -128:
sendErro = -128
uart.writechar(sendErro)
print(sendErro)
#print(clock.fps())