星瞳科技 OpenMV 的使用

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();
}
OpenMV 中下载的代码:
# 自动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())

你可能感兴趣的:(外设)