【OpenMv】学习笔记之初入江湖

OpenMV可以使用Python来进行二次开发。

Python语法

我们的魔教口号是什么?

print('hello, world')

print()函数也可以接受多个字符串,用逗号“,”隔开,print()会依次打印每个字符串,遇到逗号“,”会输出一个空格,就可以连成一串输出:

print('I am a', 'handsome', 'boy')
print(300)#直接打印整数300
print('100 + 200 =', 100 + 200)#‘字符串’

注释符号:#

对象——面向对象编程

Python对象是我一直难以理解的概念,我要把它放在前面

类(Class)和实例(Instance)

类是抽象的模板!!!,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。

#类定义一个叫Student的对象,继承于object类,这是所有类最终都会继承的类
class Student(object):
    pass

定义好了Student类,就可以根据Student类创建出Student的实例,创建实例是通过类名+()实现的:

>>> me = Student()
>>> me 
<__main__.Student object at 0x10a67a590> #0x10a67a590是内存地址,每个object的地址都不一样
>>> Student
<class '__main__.Student'>

自由地给一个实例变量绑定属性

>>>me.name = 'Iron'
>>>me.name
'Iron'

类可以起到模板的作用。因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的init方法,在创建实例的时候,就把name,score等属性绑上去:

class Student(object):
#__init__方法的第一个参数永远是self,表示创建的实例本身
    def __init__(self, name, score): #前后分别有两个下划线!!!
        self.name = name
        self.score = score

self不需要传参数

>>> me = Student('Iron', 59.9)
>>> me.name
'Iron'
>>> me.score
59.9

封装-内

class Student(object):

    def __init__(self, name, score):
        self.name = name
        self.score = score

#调用方法: name.print_score(),结果 name:99
    def print_score(self):
        print('%s: %s' % (self.name, self.score))

    #对分数分级,class类可以自由加入新的模块
    #封装的另一个好处是可以给Student类增加新的方法,比如get_grade:
    def get_grade(self):
        if self.score >= 90:
            return 'A'
        elif self.score >= 60:
            return 'B'
        else:
            return 'C'
>>>me = Student('Iron',90)
>>>you= Student('Rose',69)

>>>print(me.name, me.get_grade())
Iron A
>>>me.print_score()
Iron:90

ok
暂时学到这……

模块

import sys

条件判断if

if <条件判断1>:
    <执行1>
elif <条件判断2>:
    <执行2>
elif <条件判断3>:
    <执行3>
else:
    <执行4>

例如

age = 20
#age=0;
#age=input('Input your age: ')
#input()读取用户的输入
if age >= 6 and age <18:
    print('teenager')
elif age >= 18:
    print('adult')
else:
    print('kid')

循环while For in

for x in

sum = 0
for x in range(101):#range()函数生成一个整数序列
    sum = sum + x
print(sum)

while

#算100以内所有奇数之和
sum = 0
n = 99
while n > 0:
    sum = sum + n
    n = n - 2
print(sum)

函数

#定义一个求平方的函数
def power(x):
    return x * x

#定义一个求n次方的函数
def power(x, n):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

数据转换

>>> int(12.34)
12

对象

Python是面向对象编程的,比如一个LED灯
LED是一个类,red_led就是一个对象,可以对这个对象进行操作,比如点亮on,关掉off,查看value。

from pyb import LED
red_led = LED(1)
red_led.on()
import 

可修改的list列表

classmates = ['Michael', 'Bob', 'Tracy']
classmates
#结果:['Michael', 'Bob', 'Tracy']
classmates[-2]#索引访问,顺序和倒序访问
len(classmates)=3  #长度
classmates.insert(1, 'Jack')#插入修改
classmates[1] = 'Sarah'#替换修改

不可以修改的tuple元组

切片


>>> List = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
>>> List[1:3] #从索引1开始取,直到索引3为止,不包括3
  ['Sarah', 'Tracy']

+= 加法赋值运算符 c += a 等效于 c = c + a
= 乘法赋值运算符 c = a 等效于 c = c * a
/= 除法赋值运算符 c /= a 等效于 c = c / a
%= 取模赋值运算符 c %= a 等效于 c = c % a

<< 左移动运算符:运算数的各二进位全部左移若干位,由 << 右边的数字指定了移动的位数,高位丢弃,低位补0。a=60, a << 2 输出结果 240 ,二进制解释: 1111 0000
右移动运算符:把”>>”左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数

a = 60            # 60 = 0011 1100 
c = 0
c = a << 2;       # 240 = 1111 0000
print "5 - c 的值为:", c
 5 - c 的值为: 240

对比&& || ~
这里写图片描述

AB颜色空间

LAB:L亮度。 范围: 0-100, 0白,L=50时,就相当于50%的黑
A表示从洋红色至绿色的范围。范围:-128至+127, -128绿色 ,+127就是红色
B表示从黄色至蓝色的范围。 范围:-128至+127,-128 b是蓝色。+127 b是黄色

这里写图片描述

find_blobs函数——寻找小球

#(很多参数)
image.find_blobs(thresholds, roi=Auto, x_stride=2, y_stride=1, 
invert=False, area_threshold=10, pixels_threshold=10, 
merge=False, margin=0, threshold_cb=None, merge_cb=None)

#thresholds颜色的阈值
img=sensor.snapshot()
red_blobs = img.find_blobs([red])

#roi=Auto感兴趣区
left_roi = [0,0,160,240]
blobs = img.find_blobs([red],roi=left_roi)

#x_stride=2, y_stride=1,最小像素
blobs = img.find_blobs([red],x_stride=10)#改为10

#invert 反转阈值,把阈值以外的颜色作为阈值进行查找
invert=False

#area_threshold框面积阈值,如果色块被框起来的面积小于这个值,会被过滤掉
area_threshold=10,

#pixels_threshold 像素个数阈值,如果色块像素数量小于这个值,会被过滤掉
pixels_threshold=10, 

#merge=True合并,如果设置为True,那么合并所有重叠的blob为一个。
merge=False

#margin 边界,如果设置为1,那么两个blobs如果间距1一个像素点,也会被合并。
margin=0, threshold_cb=None, merge_cb=None

blob色块对象

blob.cx() 返回色块的外框的中心x坐标(int),也可以通过blob[5]来获取。

blob.cy() 返回色块的外框的中心y坐标(int),也可以通过blob[6]来获取。

识别颜色

# 色块监测例子 这个例子展示了如何通过find_blobs()函数来查找图像中的色块

import sensor, image, time
#threshold翻译为阈值
# 颜色追踪的例子,一定要控制环境的光,保持光线是稳定的。
#green_threshold   = (   0,   80,  -70,   -10,   -0,   30)
#green_threshold   = (   0,   80,  -20,   -0,   -80,   -30)#蓝色
green_threshold   = (   0,   80,  40,   100,   2,   60)#红色
                    #(minL, maxL, minA, maxA, minB, maxB)
#设置绿色的阈值,括号里面的数值分别是L A B 的最大值和最小值(minL, maxL, minA,
# maxA, minB, maxB),LAB的值在图像左侧三个坐标图中选取。如果是灰度图,则只需
#设置(min, max)两个数字即可。

sensor.reset() # 初始化摄像头
sensor.set_pixformat(sensor.RGB565) # 格式为 RGB565.
sensor.set_framesize(sensor.QQVGA) # 使用 QQVGA 速度快一些
sensor.skip_frames(time = 2000) # 跳过2000s,使新设置生效,并自动调节白平衡
sensor.set_auto_gain(False) # 关闭自动自动增益。默认开启的,在颜色识别中,一定要关闭白平衡。
sensor.set_auto_whitebal(False)
#关闭白平衡。白平衡是默认开启的,在颜色识别中,一定要关闭白平衡。
clock = time.clock() # 追踪帧率

while(True):
    clock.tick() # Track elapsed milliseconds between snapshots().
    img = sensor.snapshot() # 从感光芯片获得一张图像

    blobs = img.find_blobs([green_threshold])
    #find_blobs(thresholds, invert=False, roi=Auto),thresholds为颜色阈值,
    #是一个元组,需要用括号[ ]括起来。invert=1,反转颜色阈值,invert=False默认
    #不反转。roi设置颜色识别的视野区域,roi是一个元组, roi = (x, y, w, h),代表
    #从左上顶点(x,y)开始的宽为w高为h的矩形区域,roi不设置的话默认为整个图像视野。
    #这个函数返回一个列表,[0]代表识别到的目标颜色区域左上顶点的x坐标,[1]代表
    #左上顶点y坐标,[2]代表目标区域的宽,[3]代表目标区域的高,[4]代表目标
    #区域像素点的个数,[5]代表目标区域的中心点x坐标,[6]代表目标区域中心点y坐标,
    #[7]代表目标颜色区域的旋转角度(是弧度值,浮点型,列表其他元素是整型),
    #[8]代表与此目标区域交叉的目标个数,[9]代表颜色的编号(它可以用来分辨这个
    #区域是用哪个颜色阈值threshold识别出来的)。
    if blobs:
    #如果找到了目标颜色
        for b in blobs:
        #迭代找到的目标颜色区域
            # Draw a rect around the blob.
            img.draw_rectangle(b[0:4]) # rect tupe格式(x, y, w, h)
            #b[0:4]断片b中 0,1,2,3四个元素,  [0]代表识别到的目标颜色区域左上顶
            #点的x坐标  [1]代表左上顶点y坐标,
            #[2]代表目标区域的宽,[3]代表目标区域的高
            #用矩形标记出目标颜色区域
            img.draw_cross(b[5], b[6]) # cx, cy
            #在目标颜色区域的中心画十字形标记
            #b[5], b[6]是中心坐标

    print(clock.fps()) # 注意: 你的OpenMV连到电脑后帧率大概为原来的一半
    #如果断开电脑,帧率会增加

识别颜色并画个框:

画圆

image.draw_circle(x, y, radius, color=White) x,y是圆心坐标radius是圆的半径

画十字

image.draw_cross(x, y, size=5, color=White) x,y是坐标 size两侧的尺寸

画框

image.draw_rectangle(rect_tuple, color=White) 画一个矩形框 rect_tuple> 的格式是 (x, y, w, h)。

颜色形状同时识别

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))
            #将非红色的圆用白色的矩形框出来
    print("FPS %f" % clock.fps())

测距

距离 = 一个常数/直径的像素

#测量距离
#
#这个例子展示了如何通过行李中的尺寸来测量距离
#这个例子特别寻找黄色的乒乓球。
import sensor, image, time

#为了使色彩跟踪工作得非常好,理想情况下应该非常非常
#非常受控的环境,照明是恒定的......
yellow_threshold =(0,80,40,100,2,60)
#(56,83,5,57,63,80)

#您可能需要调整以上设置以跟踪绿色事物......
#在Framebuffer中选择一个区域以复制颜色设置。

sensor.reset()#初始化相机传感器。
sensor.set_pixformat(sensor.RGB565)#使用RGB565。
sensor.set_framesize(sensor.QQVGA)#使用QQVGA获取速度。
sensor.skip_frames(10)#让新设置生效。
sensor.set_auto_whitebal(False)#关闭它。
clock = time.clock()#追踪FPS。

K = 5000#应该测量的值

while(True):
       clock.tick()#跟踪快照之间经过的毫秒数()。
       img = sensor.snapshot()#拍摄照片并返回图像。
       blobs = img.find_blobs([yellow_threshold])
       if len(blobs) == 1:
       #在blob周围画一个矩形。
        b = blobs [0]
        img.draw_rectangle(b [04])#rect
        img.draw_cross(b [5],b [6])#cx,cy
        Lm = (b[2]+b[3])/2
        length = K/Lm  #距离=常数K/球像素直径
        print(length)

    #print(clock.fps())
    #注意:你的OpenMV Cam运行速度快一半
    #已连接到您的计算机。一旦断开连接,FPS应该增加。
# Hello World Example
#
# Welcome to the OpenMV IDE! Click on the green run arrow button below to run the script!

import sensor, image, time

sensor.reset() # 初始化摄像头
sensor.set_pixformat(sensor.RGB565) # 格式为 RGB565.
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(10) # 跳过10帧,使新设置生效
while(True):
    img = sensor.snapshot()         # Take a picture and return the image.
    img.draw_line((20, 30, 40, 50))
    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)
    img.draw_string(10,10, "hello world!")

效果
这里写图片描述

OpenMV的像素值是多少?

最大支持像素:
Grayscale: 640×480 and under
RGB565: 320×240 and under
Grayscale JPEG: 640×480 and under
RGB565 JPEG: 640×480 and under

焦距: 2.8mm
光圈: F2.0
尺寸: 1/3″
视角: 115°
安装: M12*0.5
红外滤光片(截断红外光): 650nm (可拆卸)
温度范围
存储 -40°C to 125°C
运行 -20°C to 70°C #难怪发热有点严重

猜你喜欢

转载自blog.csdn.net/qq_42807924/article/details/82291657