openmv电赛预备代码

该文档详细介绍了嵌入式视觉系统的一系列配置和图像处理技术,包括摄像头初始化、LED控制、图像畸变矫正、二值化、滤波等。还涵盖了模板匹配、色块追踪、舵机控制以实现物体追踪,以及线性循迹和形状识别等应用。内容涵盖了从基础设置到复杂算法的实现,是嵌入式视觉应用的实用指南。
摘要由CSDN通过智能技术生成

目录

一、初始配置

(1)摄像头配置

(2)LED初始化

(3)绘制框选

(4)串口初始化+发送+接收

二、图像处理部分

(1)畸变矫正

(2)设置图像和lcd方向

(3)图像二值化

(4)图像滤波

        ①边缘检测

        ②彩图“光线除去”

        ③核滤波

        ④环境对比度自适应

        ⑤模糊滤波

三、模板匹配

四、色块追踪

(1)色块追踪

(2)色块追踪(另一种方式)

(3)双色跟踪

五、舵机控制追踪物体

(2)双色红绿舵机

六、线性循迹

(1)巡线--彩图转黑白

(2)快速线性回归--灰度转黑白(可与模板匹配一起用)

七、测距

八、形状识别

(1)综合矩形+圆形识别

(2)识别特定大小的矩形

九、混合项目

(1)颜色形状同时识别

(2)颜色与模板匹配同时识别


一、初始配置

(1)摄像头配置

#常用头文件
import sensor, image, time, ustruct
from pyb import LED, Timer
from pyb import Pin #补光灯需要
import math, json

#传感器配置
#对比度和增益在低光场合使用
sensor.set_contrast(1) #设置图像传感器的对比度:最大值1
sensor.set_gainceiling(16) #设置图像传感器的增益上限:16
#传感器配置
sensor.reset() # 初始化摄像头
sensor.set_pixformat(sensor.GRAYSCALE)#设置图像色彩格式,有RGB565色彩图和GRAYSCALE灰度图两种
sensor.set_framesize(sensor.QQVGA)# QQ:120*160,Q最大240x320,QQQ最小60x80
sensor.skip_frames(time=2000) # 跳过10帧,使新设置生效
sensor.set_auto_whitebal(False) # 关闭自动白平衡功能(颜色识别需用)
sensor.set_auto_gain(False) # 关闭图像传感器的自动增益(颜色识别需用)
#sensor.set_vflip(True)#垂直翻转
#sensor.set_hmirror(True)#水平翻转
clock = time.clock() #创建定时对象clock

while(True):
    clock.tick()  # 计算帧率
    img =sensor.其他初始函数.lens_corr(1.8) #畸变矫正(形状识别需要,但会吃运行内存)

(2)LED初始化

import time, pyb
from pyb import LED, Timer
from pyb import Pin #补光灯需要

#补光灯
light = Timer(2, freq=50000).channel(1, Timer.PWM, pin=Pin("P6"))
light.pulse_width_percent(5) # 控制亮度 0~100

#单灯定义与使用
led = pyb.LED(3)  #Red(红)LED = 1,Green(绿)LED = 2,Blue(蓝)LED = 3,IR LEDs = 4.
led.toggle() #LED闪烁
led.on() #LED亮
led.off() #LED灭

#————————————————————————————————————其他花操作————————————————————————————————————
usb = pyb.USB_VCP() #串口通信
while(not usb.isconnected()):#如果没有连接电脑,则执行以下操作
    led.on()
    time.sleep_ms(150) #延时150ms

while(usb.isconnected()): #如果连接上电脑,则执行
    led.on()

(3)绘制框选

        img = sensor.snapshot() #获取图片    
        img.draw_line((80, 50, 100, 100), color=(255,0,0)) #画一条红色线
        img.draw_rectangle((20, 30, 41, 51), color=(255,0,0)) #画一个红色矩形
        img.draw_circle(50, 50, 30) #画一个圆
        img.draw_cross(90,60,size=10) #画一个十字线

(4)串口初始化+发送+接收

import time
from pyb import UART
import ustruct
import json

uart = UART(3,115200)   #定义串口3变量
uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters

#——————————————————————————————发送数据(方法一):包括浮点数——————————————————————————
def sending_data(find_shizi,output):
    global uart
    # 转换output为4字节的二进制形式
    output_bytes = struct.pack('f', output)
    # 构建数据包
    data_send = bytearray([0xA5, 0xA6, find_shizi]) + output_bytes + bytearray([0xFF])
    uart.write(data_send);   #必须要传入一个字节数组
#————————————————————————————————————发送数据(方法二)————————————————————————————————
#串口发送函数
def sending_data(cx,cy):
    global uart;
    data_send = ustruct.pack("<bbhhhhb",      #格式为俩个字符俩个短整型(2字节)
                    0x2C,                      #帧头1
                    0x12,                      #帧头2
                    int(cx), # up sample by 4   #数据1
                    int(cy), # up sample by 4    #数据2
                    0x5B)
    uart.write(data_send);   #必须要传入一个字节数组
    print(data_send)

#——————————————————————————————————————串口接收——————————————————————————————————

def UartReceiveDate():  #这个函数不能运行太快,否则会导致串口读取太快导致出错
    global Find_Task    #用于存储接收到的指令类型,例如42代表*,38代表&
    global Target_Num   #用于存储目标数,即数据的第三个字节
    global x            #用于索引数据数组
    global data_receive #用于存储接收到的数据
    data_receive[0] = uart.readchar() #将接收到的数据装入data_receive
    data_receive[1] = uart.readchar()
    data_receive[2] = uart.readchar()
    data_receive[3] = uart.readchar()
    data_receive[4] = uart.readchar()
    data_receive[5] = uart.readchar()
    data_receive[6] = uart.readchar()
    data_receive[7] = uart.readchar()

    #判断data数组中第x个位置的值是否为42,第x+3个位置的值是否为38,并且x的值是否小于5
    if data_receive[x] == 42 and data_receive[x+3] == 38 and x < 5:
        Find_Task =  data_receive[x+1]
        Target_Num = data_receive[x+2]
        Find_Task =  Find_Task - 48
        Target_Num = Target_Num - 48
        print(Find_Task, Target_Num)
        x = 0
    elif x >= 5: x = 0
    x+=1

二、图像处理部分

(1)畸变矫正

   解释:二维码/条形码/矩形码检测时需要使用此方法,使用畸变矫正方法来修复图像失真问题

# zoom是在对图像进行缩放的数值。默认值为1。
while(True):
    img = sensor.snapshot().lens_corr(strength = 1.7, zoom = 1.0)

(2)设置图像和lcd方向

   解释:翻转与镜像;

sensor.vflip(True) #垂直翻转
sensor.hmirror(True) #水平镜像

(3)图像二值化

   解释:这个脚本展示了二值图像滤波,可以传递二进制任意的阈值来分割图像;

#设置颜色阈值,如果是rgb图像,六个数字分别为(minL, maxL, minA, maxA, minB, maxB);
#如果是灰度图,则只需设置(min, max)两个数字即可。
red_threshold = (0, 40, 18, 127, -128, 127) # L A B阈值
#使用工具 - >机器视觉 - >阈值编辑器选择更好的阈值。
while(True):
    clock.tick()
    img = sensor.snapshot()
    img.binary([red_threshold])

(4)图像滤波

        ①边缘检测

        解释:这个程序示范了在图像上使用morph函数来进行边缘检测;

import sensor, image, time
#设置核函数滤波,核内每个数值值域为[-128,127],核需为列表或元组
kernel_size = 1 # kernel width = (size*2)+1, kernel height = (size*2)+1
kernel = [-1, -1, -1,\
          -1, +8, -1,\
          -1, -1, -1]
thresholds = [(100, 255)] # 设置阈值
# 在OV7725 sensor上, 边缘检测可以通过设置sharpness/edge寄存器来增强。
# 注意:这将在以后作为一个函数实现
if (sensor.get_id() == sensor.OV7725):
    sensor.__write_reg(0xAC, 0xDF)
    sensor.__write_reg(0x8F, 0xFF)

while(True):
    img = sensor.snapshot() # 拍一张照片,返回图像
    img.morph(kernel_size, kernel)
    #morph(size, kernel, mul=Auto, add=0),morph变换,mul根据图像对比度
    #进行调整,mul使图像每个像素乘mul;add根据明暗度调整,使得每个像素值加上add值。
    #如果不设置则不对morph变换后的图像进行处理。

    img.binary(thresholds)#利用binary函数对图像进行分割
    img.erode(1, threshold = 2)# 腐蚀像素小于2邻居使用3x3图像内核
    #侵蚀函数erode(size, threshold=Auto),去除边缘相邻处多余的点。threshold
    #用来设置去除相邻点的个数,threshold数值越大,被侵蚀掉的边缘点越多,边缘旁边
    #白色杂点少;数值越小,被侵蚀掉的边缘点越少,边缘旁边的白色杂点越多。
        ②彩图“光线除去”

        解释:此示例显示如何从图像中删除明亮的灯光,您可以使用带有“zero =”参数的binary()方法执行此操作。从图像中删除明亮的光线允许您在图像上使用histeq(), 而不会使图像的过饱和部分的异常值破坏算法;

import sensor, image, time
thresholds = (90, 100, -128, 127, -128, 127)
while(True):
    img = sensor.snapshot().binary([thresholds], invert=False, zero=True)
        ③核滤波

        解释:核可以用于图像处理中的边缘检测,它会突出图像中的边缘

import sensor, image, time
kernel_size = 1 # 3x3==1, 5x5==2, 7x7==3, etc.
kernel = [-2, -1,  0, \
          -1,  1,  1, \
           0,  1,  2]
while(True):
    img = sensor.snapshot() # 拍一张照片,返回图像   
    img.morph(kernel_size, kernel)# 在图像的每个像素上运行核
        ④环境对比度自适应

        解释:此示例展示了如何使用自适应直方图均衡来改善图像中的对比度。自适应直方图均衡将图像分割成区域,然后均衡这些区域中的直方图,以改善图像对比度与全局直方图均衡化。此外,您可以指定剪辑限制以防止对比度变得狂野。

import sensor, image, time

while(True):
    # clip_limit <0为您提供正常的自适应直方图均衡,这可能会导致大量的对比噪音...
    # clip_limit=1 什么都不做。为获得最佳效果,请略高于1,如下所示。
    # 越高,越接近标准自适应直方图均衡,并产生巨大的对比度波动。
    img = sensor.snapshot().histeq(adaptive=True, clip_limit=3)#通过改变clip_limit的值来改变对比度的自适应效果
    #img = sensor.snapshot().histeq()
        ⑤模糊滤波

        解释:用于对图像进行平滑处理,去除图像中的噪声或细节;

import sensor, image, time
while(True):
    img = sensor.snapshot() # 拍一张照片,返回图像  
    img.gaussian(1) #值越大,滤波效果越明显,图像越模糊

三、模板匹配

import pyb, sensor, image, math, time
from image import SEARCH_EX, SEARCH_DS

template1 = image.Image("/0.pgm")

while(True):
    clock.tick()
    img = sensor.snapshot()
    r1=0
    r1 = img.find_template(template1, 0.70, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    if r1:
        img.draw_rectangle(r1)
        print(r1)
        uart.write("0")
#—————————————————————————————多模板匹配(危)—————————————————————————————————————————
# 这个例子展示了如何使用OpenMV凸轮的NCC功能将小部分图像与图像的各个部分
# 进行匹配...期望获得极其可控的环境NCC并不是全部有用的。
import time, sensor, image
from image import SEARCH_EX, SEARCH_DS

sensor.reset()
sensor.set_contrast(1)
sensor.set_gainceiling(16)
sensor.set_framesize(sensor.QQVGA)
sensor.set_pixformat(sensor.GRAYSCALE)

templates = ["/0.pgm", "/1.pgm", "/2.pgm", "/6.pgm"] #保存多个模板
#加载模板图片

clock = time.clock()

# Run template matching
while (True):
    clock.tick()
    img = sensor.snapshot()
    #多模板匹配
    for t in templates:
        template = image.Image(t)
        #对每个模板遍历进行模板匹配
        r = img.find_template(template, 0.70,roi=(10,15,70,40) ,step=4 ,search=SEARCH_EX) #, roi=(10, 0, 60, 60))
        if r != None:  #模板识别
            find_biaozhi=1
            print(find_biaozhi)
            img.draw_rectangle(r, color=220)
        else:
            find_biaozhi=0

四、色块追踪

red = (xxx,xxx,xxx,xxx,xxx,xxx)
blue = (xxx,xxx,xxx,xxx,xxx,xxx)
yellow = (xxx,xxx,xxx,xxx,xxx,xxx)

img=sensor.snapshot()
red_blobs = img.find_blobs([red])

color_blobs = img.find_blobs([red,blue, yellow]) #多颜色寻找

 (1)色块追踪

import sensor, image, time,math,pyb
from pyb import UART,LED
import json
import ustruct

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_whitebal(False) # 自动白平衡功能(颜色识别需用)
sensor.set_auto_gain(False) # 关闭图像传感器的自动增益(颜色识别需用)
clock = time.clock()

red_threshold=(63, 91, -67, -23, 40, 78) #目标颜色阈值
uart = UART(3,115200)   #定义串口3变量
uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters

def find_max(blobs):    #定义寻找色块面积最大的函数
    max_size=0
    for blob in blobs:
        if blob.pixels() > max_size:
            max_blob=blob
            max_size = blob.pixels()
    return max_blob

cx=0
cy=0
w=0
h=0
s=0
while(1):
    img = sensor.snapshot()
    blobs = img.find_blobs([red_threshold]) 
    if blobs:    #如果找到了目标颜色
            max_b = find_max(blobs)    
            w=max_b[1]
            h=max_b[2]
            cx=max_b[5]
            cy=max_b[6]
            s=w*h
            img.draw_rectangle(max_b[0:4]) # 框选色块
            img.draw_cross(max_b[5], max_b[6]) # 色块的中心坐标
            FH = bytearray([0x2C,0x12,cx,cy,s,0x5B])
            uart.write(FH)

(2)色块追踪(另一种方式)

import sensor, image, time

red_threshold_01 = (40, 52, 40, 50, 0, 50) #阈值
# 初始化设置
sensor.reset() 
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA) 
sensor.skip_frames(time=2000) 
sensor.set_auto_whitebal(False) # 自动白平衡功能(颜色识别需用)
sensor.set_auto_gain(False) # 关闭图像传感器的自动增益(颜色识别需用)
clock = time.clock()  

#变量定义
last_blobs = None  # 初始化last_blobs

#色块追踪(改进版)封装代码
def color_detection(img, threshold, last_blobs=None, roi_offset=7, roi_extend=12, area_threshold=1000):
    if last_blobs:
        for b in last_blobs:
            x1 = b[0] - roi_offset
            y1 = b[1] - roi_offset
            w1 = b[2] + roi_extend
            h1 = b[3] + roi_extend

        roi2 = (x1, y1, w1, h1)
        blobs = img.find_blobs([threshold], roi=roi2, area_threshold=area_threshold)
    else:
        blobs = img.find_blobs([threshold], area_threshold=area_threshold)

    if blobs:
        for b in blobs:
            img.draw_rectangle(b[0:4]) 
            img.draw_cross(b[5], b[6])  # 绘制色块中心点的十字标记
            print("色块中心坐标:", b[5], b[6])  # 打印色块中心点的x、y坐标

    return blobs

while True:
    clock.tick()
    img = sensor.snapshot()
    
    # 调用改进的颜色检测函数
    blobs = color_detection(img, red_threshold_01, last_blobs)  
    last_blobs = blobs  # 更新last_blobs

    #print("帧率:", clock.fps())

(3)双色跟踪

import sensor, image, time, math, pyb
from pyb import UART, LED
import json
import ustruct

# 在颜色识别中需要关闭“白平衡”和“自动增益”
sensor.set_auto_whitebal(False)
sensor.set_auto_gain(False)

# 设置两种颜色的阈值
red_threshold = (63, 91, -67, -23, 40, 78)
green_threshold = (your_green_threshold_values)

uart = UART(3, 115200)
uart.init(115200, bits=8, parity=None, stop=1)

def find_max(blobs):
    max_size = 0
    max_blob = None
    for blob in blobs:
        if blob.pixels() > max_size:
            max_blob = blob
            max_size = blob.pixels()
    return max_blob

while True:
    img = sensor.snapshot()
    
    # 找到红色色块
    red_blobs = img.find_blobs([red_threshold])
    if red_blobs:
        max_red_blob = find_max(red_blobs)
        red_w = max_red_blob[1]
        red_h = max_red_blob[2]
        red_cx = max_red_blob[5]
        red_cy = max_red_blob[6]
        red_s = red_w * red_h
        img.draw_rectangle(max_red_blob[0:4]) # 框选红色色块
        img.draw_cross(max_red_blob[5], max_red_blob[6]) # 红色色块的中心坐标
        sending_data(red_cx, red_cy, red_s)
    
    # 找到绿色色块
    green_blobs = img.find_blobs([green_threshold])
    if green_blobs:
        max_green_blob = find_max(green_blobs)
        green_w = max_green_blob[1]
        green_h = max_green_blob[2]
        green_cx = max_green_blob[5]
        green_cy = max_green_blob[6]
        green_s = green_w * green_h
        img.draw_rectangle(max_green_blob[0:4]) # 框选绿色色块
        img.draw_cross(max_green_blob[5], max_green_blob[6]) # 绿色色块的中心坐标
        sending_data(green_cx, green_cy, green_s)

五、舵机控制追踪物体

   需要用上:PID

import sensor, image, time
from pid import PID
from pyb import Servo

pan_servo=Servo(1)
tilt_servo=Servo(2)

pan_servo.calibration(500,2500,500)
tilt_servo.calibration(500,2500,500)

red_threshold  = (13, 49, 18, 61, 6, 47)

#pan_pid = PID(p=0.07, i=0, imax=90) #脱机运行或者禁用图像传输,使用这个PID
#tilt_pid = PID(p=0.05, i=0, imax=90) #脱机运行或者禁用图像传输,使用这个PID
pan_pid = PID(p=0.1, i=0, imax=90)#在线调试使用这个PID
tilt_pid = PID(p=0.1, i=0, imax=90)#在线调试使用这个PID

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.RGB565) # use RGB565.
sensor.set_framesize(sensor.QQVGA) # use QQVGA for speed.
sensor.skip_frames(10) # Let new settings take affect.
sensor.set_auto_whitebal(False) # turn this off.
clock = time.clock() # Tracks FPS.

#筛选出最大的色块
def find_max(blobs):
    max_size=0
    for blob in blobs:
        if blob[2]*blob[3] > max_size:
            max_blob=blob
            max_size = blob[2]*blob[3]
    return max_blob

while(True):
    clock.tick() # Track elapsed milliseconds between snapshots().
    img = sensor.snapshot() # Take a picture and return the image.

    blobs = img.find_blobs([red_threshold])
    if blobs:
        max_blob = find_max(blobs)
        pan_error = max_blob.cx()-img.width()/2
        tilt_error = max_blob.cy()-img.height()/2

        print("pan_error: ", pan_error)

        img.draw_rectangle(max_blob.rect()) # rect
        img.draw_cross(max_blob.cx(), max_blob.cy()) # cx, cy

        pan_output=pan_pid.get_pid(pan_error,1)/2
        tilt_output=tilt_pid.get_pid(tilt_error,1)
        print("pan_output",pan_output)
        #控制舵机
        pan_servo.angle(pan_servo.angle()+pan_output) #水平移动
        tilt_servo.angle(tilt_servo.angle()-tilt_output) #垂直移动

(2)双色红绿舵机

import sensor, image, time
from pid import PID
from pyb import Servo

pan_servo = Servo(1)
tilt_servo = Servo(2)

pan_servo.calibration(500, 2500, 500)
tilt_servo.calibration(500, 2500, 500)

red_threshold = (13, 49, 18, 61, 6, 47)
green_threshold = (37, 100, -64, -25, -17, 38)

pan_pid = PID(p=0.1, i=0, imax=90)
tilt_pid = PID(p=0.1, i=0, imax=90)

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(10)
sensor.set_auto_whitebal(False)
clock = time.clock()

# 筛选出最大的色块
def find_max(blobs):
    max_size = 0
    for blob in blobs:
        if blob[2] * blob[3] > max_size:
            max_blob = blob
            max_size = blob[2] * blob[3]
    return max_blob

while True:
    clock.tick()
    img = sensor.snapshot()

    # 分别找到红色和绿色色块
    red_blobs = img.find_blobs([red_threshold])
    green_blobs = img.find_blobs([green_threshold])

    # 选择要追踪的物体,比如选择红色物体
    if red_blobs:
        max_blob = find_max(red_blobs)
    elif green_blobs:
        max_blob = find_max(green_blobs)
    else:
        max_blob = None

    if max_blob:
        pan_error = max_blob.cx() - img.width() / 2
        tilt_error = max_blob.cy() - img.height() / 2

        print("pan_error: ", pan_error)

        img.draw_rectangle(max_blob.rect())
        img.draw_cross(max_blob.cx(), max_blob.cy())

        pan_output = pan_pid.get_pid(pan_error, 1) / 2
        tilt_output = tilt_pid.get_pid(tilt_error, 1)

        # 控制舵机
        pan_servo.angle(pan_servo.angle() + pan_output)
        tilt_servo.angle(tilt_servo.angle() - tilt_output)

六、线性循迹

(1)巡线--彩图转黑白

THRESHOLD = (0, 40, -128, 11, -6, 46) # 设置阈值
threshold = 100
import sensor, image, time
from pyb import LED
from pid import PID
from image import SEARCH_EX, SEARCH_DS #模板识别

#如果要制作巡线小车的话,只需利用本程序得到的line对象的theta返回值和rho,
#theta代表返回线段的角度, rho代表偏移的距离),利用theta和rho来控制小车角度即可。
#rho更重要一些,如果不用theta,只用rho也是可以的。
rho_pid = PID(p=0.4, i=0) #rho代表偏移的距离
theta_pid = PID(p=0.001, i=0) #theta代表返回线段的角度:小车可以利用直线返回的角度控制移动
                              #通过角度偏移对左右两边的电机进行速度的控制
sensor.set_pixformat(sensor.RGB565)

while(True):
    img = sensor.snapshot().binary([THRESHOLD])# 获取图像的快照,并将其二值化处理,根据之前定义的阈值将图像转换为二值图像
    #巡线
    line = img.get_regression([(100,100)], robust = True)#在二值图像中检测线条
    if (line):                                           #get_regression函数返回一个线条对象,包含了线条的信息,如位置、角度和长度
        rho_err = abs(line.rho())-img.width()/2 #计算线条距离图像中心的偏差
        if line.theta()>90: #检查线条的角度是否大于90度。
            theta_err = line.theta()-180 #将角度限制在-90度到90度的范围内
        else:
            theta_err = line.theta() #将线条的角度赋值给theta_err变量
        img.draw_line(line.line(),color = 127) #在图像上绘制检测到的线条(蓝线)
        print(rho_err,line.magnitude(),rho_err) #打印线条距离中心的偏差值,线条的长度,距离中心的偏差值
        if line.magnitude()>8: #检查线条的长度是否大于8
            rho_output = rho_pid.get_pid(rho_err,1) #使用PID控制器,计算线条距离中心的偏差的输出值
            theta_output = theta_pid.get_pid(theta_err,1) #使用PID控制器,计算角度偏差的输出值
            output = rho_output+theta_output #将线条距离中心的偏差输出值和角度偏差输出值相加,得到最终的输出值
            print(output)

(2)快速线性回归--灰度转黑白(可与模板匹配一起用)

  解释:这被称为快速线性回归,因为我们使用最小二乘法来拟合线。然而,这种方法对于任何具有很多(或者甚至是任何)异常点的图像都是不好的,这会破坏线条拟合.

GRAYSCALE_THRESHOLD = (0, 40, -128, 11, -6, 46)#设置阈值,(0,100)检测黑色线
BINARY_VISIBLE = True # 首先执行二进制操作,以便您可以看到正在运行的线性回归...虽然可能会降低FPS。
import sensor, image, time
from pyb import UART
import struct
def sending_data(x1,y1,x2,y2):
    data =struct.pack("<bbhhhhb",              #格式为俩个字符俩个短整型(2字节)
                   0x2C,                       #帧头1
                   0x12,                       #帧头2
                   int(x1), # up sample by 4    #数据1,低位在前
                   int(y1), # up sample by 4    #数据2
                   int(x2),
                   int(y2),
                   )
    uart.write(data);   #必须要传入一个字节数组
    print(data)

sensor.set_pixformat(sensor.GRAYSCALE) #(重要)让图像一开始就是灰度的
#其他配置
uart = UART(3, 115200)

while(True):
    img = sensor.snapshot().histeq()
    img.mean(2)#进行平均滤波
    img.binary([GRAYSCALE_THRESHOLD])#对图像进行黑白分割
    img.erode(1)

    # 函数返回回归后的线段对象line,有x1(), y1(), x2(), y2(), length(), theta(), rho(), magnitude()参数。
    # x1 y1 x2 y2分别代表线段的两个顶点坐标,length是线段长度,theta是线段的角度。
    # magnitude表示线性回归的效果,(0,+∞)范围内,其中0代表一个圆。越好值越大。
    line = img.get_regression([(255,255) if BINARY_VISIBLE else THRESHOLD])
    if (line):
        img.draw_line(line.line(), color = 255)
        sending_data(line.x1(),line.y1(),line.x2(),line.y2())
        print("x1 = %d, y1 = %d, x2 = %d, y2 = %d" % (line.x1(), line.y1(), line.x2(), line.y2() if (line) else "N/A"))
    #利用顶点坐标循迹
# 关于负rho值:
# A [theta+0:-rho]元组与[theta+180:+rho]相同

七、测距

import sensor, image, time
#画面动他就检测
red_threshold   = (0, 15, -40, 0, 0, 40)
#yellow_threshold   = ( 56,   83,    5,   57,   63,   80)

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.RGB565) # use RGB565.
sensor.set_framesize(sensor.QQVGA) # use QQVGA for speed.
sensor.skip_frames(10) # Let new settings take affect.
sensor.set_auto_whitebal(False) # 关闭白平衡(因为是色块识别)
clock = time.clock() # Tracks FPS.

K=5000 #需要测量后重新定义

while(True):
    clock.tick()
    img = sensor.snapshot()

    blobs = img.find_blobs([red_threshold])
    if len(blobs) == 1:  #
        # Draw a rect around the blob.
        b = blobs[0]
        img.draw_rectangle(b[0:4]) #使用矩形的坐标绘制一个矩形框在图像上
        img.draw_cross(b[5], b[6]) #绘制一个十字形在图像上
        Lm = (b[2]+b[3])/2
        length = K/Lm
        print(length) #距离 = 一个常数 / 直径的像素(小球)

八、形状识别

(1)综合矩形+圆形识别

import sensor, image, time

# 初始化相机设置
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time=2000)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
clock = time.clock()

while True:
    clock.tick()
    #lens_corr(1.8)畸变矫正
    img = sensor.snapshot()

    # 寻找圆形
    for c in img.find_circles(threshold=3500, x_margin=20, y_margin=20, r_margin=20, r_min=2, r_max=100):
        img.draw_circle(c.x(), c.y(), c.r(), color=(255, 0, 0))  # 画圆
        print("圆形:x={}, y={}, r={}".format(c.x(), c.y(), c.r()))

    # 寻找矩形
    for r in img.find_rects(threshold=35000): # 降低阈值,提高矩形的检测敏感性
        img.draw_rectangle(r.rect(), color=(0, 255, 0))  # 画矩形
        print("矩形:x={}, y={}, w={}, h={}".format(r.x(), r.y(), r.w(), r.h()))


    print("FPS: ", clock.fps())

(2)识别特定大小的矩形

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time=2000)
sensor.set_auto_gain(False)
sensor.set_auto_whitebal(False)
clock = time.clock()

endbox_num=0
while(True):
    img = sensor.snapshot()
    # 下面的`threshold应设置为足够高的值,以滤除在图像中检测到的具有低边缘幅度的噪声矩形
    # 最适用与背景形成鲜明对比的矩形。
    for r in img.find_rects(threshold = 10000):
        endbox_size = r.magnitude()
        if (endbox_size<24000 and r.h()<25 and r.w()<25) :
            endbox_num = endbox_num + 1
            img.draw_rectangle(r.rect(), color = (255, 0, 0))
        print(r.x())
    print(endbox_num)

九、混合项目

(1)颜色形状同时识别

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
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()

while(True):
    clock.tick()
    img = sensor.snapshot().lens_corr(1.8)
    for c in img.find_circles(threshold = 3500, x_margin = 10, y_margin = 10, r_margin = 10,
            r_min = 2, r_max = 100, r_step = 2):
        area = (c.x()-c.r(), c.y()-c.r(), 2*c.r(), 2*c.r())
        #area为识别到的圆的区域,即圆的外接矩形框
        statistics = img.get_statistics(roi=area)#像素颜色统计
        print(statistics)
        #(0,100,0,120,0,120)是红色的阈值,所以当区域内的众数(也就是最多的颜色),范围在这个阈值内,就说明是红色的圆。
        #l_mode(),a_mode(),b_mode()是L通道,A通道,B通道的众数。
        if 0<statistics.l_mode()<100 and 0<statistics.a_mode()<127 and 0<statistics.b_mode()<127:#if the circle is red
            img.draw_circle(c.x(), c.y(), c.r(), color = (255, 0, 0))#识别到的红色圆形用红色的圆框出来
        else:
            img.draw_rectangle(area, color = (255, 255, 255))
            #将非红色的圆用白色的矩形框出来

(2)颜色与模板匹配同时识别

# 多颜色多模板匹配示例
import sensor, image, time
from image import SEARCH_EX, SEARCH_DS

# 颜色跟踪阈值(L Min, L Max, A Min, A Max, B Min, B Max)
# 下面的阈值跟踪一般红色/绿色的东西。你不妨调整他们...
thresholds = [(30, 100, 15, 127, 15, 127), # generic_red_thresholds
              (30, 100, -64, -8, -32, 32), # generic_green_thresholds
              (0, 15, 0, 40, -80, -20)] # generic_blue_thresholds
# 不要超过16个颜色阈值
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
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()

templates = ["/0.pgm", "/1.pgm", "/2.pgm", "/6.pgm"] #保存多个模板

while(True):
    clock.tick()
    img = sensor.snapshot()
    for blob in img.find_blobs(thresholds, pixels_threshold=200, area_threshold=200):
        #img.draw_rectangle(blob.rect())
        #img.draw_cross(blob.cx(), blob.cy())
        #print(blob.code())

        img = img.to_grayscale()
        for t in templates:
            template = image.Image(t)
            #对每个模板遍历进行模板匹配
            r = img.find_template(template, 0.70, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
        #find_template(template, threshold, [roi, step, search]),threshold中
        #的0.7是相似度阈值,roi是进行匹配的区域(左上顶点为(10,0),长80宽60的矩形),
        #注意roi的大小要比模板图片大,比frambuffer小。
        #把匹配到的图像标记出来
            if r:
                img.draw_rectangle(r, color=0)
                print(blob.code(), t) #打印模板名字
                #如果为红色, blob.code()==1; 如果为绿色, blob.code==2.
                #如果为数字0, t=="0.pgm"; 如果为数字1, t=="1.pgm".
  • 15
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值