前言: 视觉小车最重要的是视觉功能,其实现方式主要有:
- Opencv+外置计算机摄像头。需要计算机作为上位机。
- Stm32+OV7670。较难,大师级。
- OpenMV摄像头。较简单,入门级。
博主刚开始为了准备项目,了解尝试过前两种方式,最后才终于接触到OpenMV这种主控板,因为其开发简单、结构简单、非常适合用于智能小车,入门虽然简单,功能却十分强大。
OpenMV简介:
OpenMV的目标是成为“机器视觉世界的Arduino ",有自己的IDE,采用Python二次开发简单易用,可扩展,开源,详细教程和技术手册。
OpenMV3是主要以STM32F427CPU为核心,集成了OV7725摄像头的模块。
OpenMV的功能:
颜色追踪、路线识别、形状识别、二维码识别、人脸识别、瞳孔追踪等。
上图来源
入手准备:
- OpenMV3 M7摄像头实物。(博主入手的OpenMV主控板来自于星瞳科技, 手边有实物更容易开发)
- 官网下载安装的IDE。(集成开发环境,是集成了代码编写、分析、编译、调试功能的软件)
OpenMV采用 Python 给用户开发,而Python简单易学,简洁强大,在视觉开发方面十分突出。下文是初步学习使用 OpenMV 模块和入门到拓展学习Python语法
初步使用 OpenMV:
其实初步学习使用的话,官网的十分钟上手教程已经非常详细,推荐大家去看。(其实博主不是懒,是怕不专业误导你们~)
其中需要注意的是LAB颜色空间:
LAB:L亮度。 范围: 0-100, 0白,L=50时,就相当于50%的黑
A表示从洋红色至绿色的范围。范围:-128至+127, -128绿色 ,+127就是红色
B表示从黄色至蓝色的范围。 范围:-128至+127,-128 b是蓝色。+127 b是黄色
学习Python语法:
推荐学习Python的网站:
- Python 基础教程 | 菜鸟教程
- Python教程 - 廖雪峰的官方网站
- python基础教程-w3cschool
博主的Python学习笔记:
主要克隆之前的文章:【OpenMv】学习笔记之初入江湖
语句 Print
我们的魔教口号是什么?
print('hello, world')
print()函数也可以接受多个字符串,用逗号“,”隔开,print()会依次打印每个字符串,遇到逗号“,”会输出一个空格,就可以连成一串输出:
print('I am a', 'handsome', 'boy')
print(300)
print('100 + 200 =', 100 + 200)
注释符号:#
模块 py
:
以屁眼.py结尾的就是一个模块
import 语句,引入模块,需要在开始就引用,就是c语言的头文件吧
import 模块名.函数名
import sys
语句 from…import
:
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。语法如下:
from fib import fibonacci
函数:
函数就是可以实现功能的方式,可重复调用。
类型有:
以下源代码实现功能:定义一个plus(x,y)
函数,将x+y的结果输出。
def plus(x,y):
a=x+y
return(a)
使用截图:
以下源代码实现功能:定义一个求平方的power(x)
函数,将 x 的平方输出。
def power(x):
return x * x
以下源代码实现功能:定义一个n次方的power(x, n)
函数,将 x 的 n 次方输出。
def power(x, n):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
条件判断 if
:
用法:
if <条件判断1>:
<执行1>
elif <条件判断2>:
<执行2>
elif <条件判断3>:
<执行3>
else:
<执行4>
以下源代码实现功能:输入年龄,用 if 判断是 kid 还是 teenager 还是 adult 。
age = 20
if age >= 6 and age <18:
print('teenager')
elif age >= 18:
print('adult')
else:
print('kid')
循环 while
和 For x in range(y)
:
以下源代码实现功能:采用 for x in range(100)
计算 0+1+2+...+99
的和。
sum = 0
for x in range(100):
sum = sum + x
print(sum)
以下源代码实现功能:采用 while循环
计算100以内所有奇数之和。
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
数据类型转换 int
:
以下源代码实现功能:调用int
函数将浮点型转化为整形。
>>> int(12.34)
12
可修改的list列表:
classmates = ['Michael', 'Bob', 'Tracy']
classmates
classmates[-2]
len(classmates)=3
classmates.insert(1, 'Jack')
classmates[1] = 'Sarah'
切片:
>>> List = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
>>> List[1: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
c = 0
c = a << 2;
print "5 - c 的值为:", c
5 - c 的值为: 240
逻辑运算符 && || ~
:
对象——面向对象编程:
Python是面向对象编程的,比如一个LED灯
LED是一个类,red_led就是一个对象,可以对这个对象进行操作,比如点亮on,关掉off,查看value。
from pyb import LED
red_led = LED(1)
red_led.on()
类(Class)和实例(Instance):
类是抽象的模板!!!,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
class Student(object):
pass
定义好了Student类,就可以根据Student类创建出Student的实例,创建实例是通过类名+()
实现的:
>>> me = Student()
>>> me
<__main__.Student object at 0x10a67a590>
>>> Student
<class '__main__.Student'>
自由地给一个实例变量绑定属性
>>>me.name = 'Iron'
>>>me.name
'Iron'
类可以起到模板的作用。因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法,在创建实例的时候,就把name,score等属性绑上去:
class Student(object):
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
def print_score(self):
print('%s: %s' % (self.name, self.score))
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
以下是开始主要用到的源代码例子以及拓展。
识别颜色例子:
import sensor, image, time
green_threshold = ( 0, 80, 40, 100, 2, 60)
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()
img = sensor.snapshot()
blobs = img.find_blobs([green_threshold])
if blobs:
for b in blobs:
img.draw_rectangle(b[0:4])
img.draw_cross(b[5], b[6])
print(clock.fps())
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)
img=sensor.snapshot()
red_blobs = img.find_blobs([red])
left_roi = [0,0,160,240]
blobs = img.find_blobs([red],roi=left_roi)
blobs = img.find_blobs([red],x_stride=10)
invert=False
area_threshold=10,
pixels_threshold=10,
merge=False
margin=0, threshold_cb=None, merge_cb=None
blob色块对象:
blob.cx() 返回色块的外框的中心x坐标(int),也可以通过blob[5]来获取。
blob.cy() 返回色块的外框的中心y坐标(int),也可以通过blob[6]来获取。
绘图例子:
import sensor, image, time
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(10)
while(True):
img = sensor.snapshot()
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!")
画圆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)
sensor.set_auto_whitebal(False)
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())
statistics = img.get_statistics(roi=area)
print(statistics)
if 0<statistics.l_mode()<100 and 0<statistics.a_mode()<127 and 0<statistics.b_mode()<127:
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)
#您可能需要调整以上设置以跟踪绿色事物......
#在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 [0:4])
img.draw_cross(b [5],b [6])#cx,cy
Lm = (b[2]+b[3])/2
length = K/Lm
print(length)
#注意:你的OpenMV Cam运行速度快一半
#已连接到您的计算机。一旦断开连接,FPS应该增加。
坐标和图像大小
设置图像大小
sensor.set_framesize() 设置图像的大小
sensor.QQVGA: 160x120
sensor.QQVGA2: 128x160 (用于 lcd 扩展板)
sensor.HQVGA: 240x160
sensor.QVGA: 320x240
sensor.VGA: 640x480 (只用于OpenMV Cam M7 的灰度图处理图像,或者彩图采集图像)
sensor.QQCIF: 88x72
sensor.QCIF: 176x144
sensor.CIF: 352x288
结语:
OpenMV非常适用于视觉识别,开发简单,功能强大。学好 Python 是学好 OpenMV 的基础,而如何学好 Python 并不是一蹴而就的事情。
骐骥一跃,不能十步;驽马十驾,功在不舍。——《荀子》
此篇收录于专栏【手把手教你做OpenMV小车】,总篇链接:https://blog.csdn.net/qq_42807924/article/details/86585757
完。
(本文为吾本虚无原创,禁止任何形式转载)
全文完。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)