前言: 视觉小车最重要的是视觉功能,其实现方式主要有:

  • 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)#直接打印整数300
print('100 + 200 =', 100 + 200)#‘字符串’

注释符号:#

模块 py:

以屁眼.py结尾的就是一个模块
import 语句,引入模块,需要在开始就引用,就是c语言的头文件吧

import 模块名.函数名

import sys

语句 from…import

Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。语法如下:

#例如,要导入模块 fib 的 fibonacci 函数,使用如下语句:from fib import fibonacci

函数:

函数就是可以实现功能的方式,可重复调用。
类型有:

  • 无参数无返回
  • 无参数有返回
  • 有参数无返回
  • 有参数有返回

以下源代码实现功能:定义一个plus(x,y)函数,将x+y的结果输出。

def plus(x,y):a=x+yreturn(a)#输入参数x,y,求出x+y#有入口参数和返回值

使用截图:

以下源代码实现功能:定义一个求平方的power(x)函数,将 x 的平方输出。

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

以下源代码实现功能:定义一个n次方的power(x, n)函数,将 x 的 n 次方输出。

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

条件判断 if

用法:

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

以下源代码实现功能:输入年龄,用 if 判断是 kid 还是 teenager 还是 adult 。

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')

循环 whileFor x in range(y):

以下源代码实现功能:采用 for x in range(100) 计算 0+1+2+...+99 的和。

# 注意从0开始加,没有加100。
sum = 0
for x in range(100):# range()函数生成一个整数序列sum = sum + x
print(sum)

以下源代码实现功能:采用 while循环 计算100以内所有奇数之和。

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

数据类型转换 int

以下源代码实现功能:调用int函数将浮点型转化为整形。

>>> int(12.34)
12

可修改的list列表:

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

切片:

>>> 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 的值为:", c5 - c 的值为: 240

逻辑运算符 && || ~:

对象——面向对象编程:

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

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

类(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 = nameself.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 = nameself.score = score#调用方法: name.print_score(),结果 name:99def 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

以下是开始主要用到的源代码例子以及拓展。

识别颜色例子:

# 色块监测例子 这个例子展示了如何通过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连到电脑后帧率大概为原来的一半#如果断开电脑,帧率会增加

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]来获取。

绘图例子:

# Hello World Example
#
# Welcome to the OpenMV IDE! Click on the green run arrow button below to run the script!import sensor, image, timesensor.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!")

画圆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, timesensor.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 redimg.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 [0:4])#rectimg.draw_cross(b [5],b [6])#cx,cyLm = (b[2]+b[3])/2length = K/Lm  #距离=常数K/球像素直径print(length)#print(clock.fps())#注意:你的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
完。

(本文为吾本虚无原创,禁止任何形式转载)

全文完。

【OpenMV小车——第1.2篇】OpenMV主控板的简介与入门使用相关推荐

  1. 基于stm32的两轮自平衡小车3(硬件篇)

    此篇为硬件篇,接上一篇"基于stm32的两轮自平衡小车2(原理篇)".包含自行设计电路板原理图与PCB电路图的过程.详见目录. 目录 stm32管脚分配 硬件原理图 PCB电路图 ...

  2. openmv底层算法剖析---梦飞openmv前传

    前言 接梦飞openmv博客,本篇重点剖析openmv的算法和功能实现.openmv是国外开源团队依托mirco-python架构开发的一套基于stm32内核优化算法的图像识别模组,其目的是让图像视觉 ...

  3. 【开源硬件篇】STM32F103C8T6主控板

    STM32F103C8T6主控板 文章目录 STM32F103C8T6主控板 设计目标 一.STM32F103C8T6核心板外围引脚电路 1.1 原理图设计 1.2 PCB设计用例 二.ISP一键下载 ...

  4. microbit编程_使用图形化编程实现主控板与手机蓝牙通讯(2019.3.25)

    本文转自:DFRobot创客社区 原文链接: [Mind+]使用图形化编程实现主控板与手机蓝牙通讯-Mind+论坛-DF创客社区​mc.dfrobot.com.cn 本帖最后由 Forgotten 于 ...

  5. 认识一下小龟机器人主控板

    简要 小龟机器人主控板采用乐鑫ESP32处理器,总共有23组可控制管脚,所以最多支持23个舵机.4个电机.10根可输入输出编程管脚.23根管脚全部支持输出控制. 正面插口说明 电源区 5V电源插口 由 ...

  6. Python之路【第一篇】:Python简介和入门

    Python之路[第一篇]:Python简介和入门 Python简介 Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗 ...

  7. mpython掌控板作品_第1课 Arduino micro:bit 掌控板 创客教育常用的3类主控板

    有很多朋友想学习创客,问我怎么学习.我建议他先百度一下"创客",看看有什么感觉.结果还是很懵,五花八门,什么都有,找不到核心.简单理解,就是以前讲的DIY,自己动手,制作一个东西. ...

  8. 串口 能 按位传输吗_、 迪文串口屏TTL与主控板RS232电平信号转换方案

    迪文串口屏TTL与主控板RS232电平信号转换方案 一.TTL和RS232简述 串口.COM口是指的物理接口形式(硬件),按位(bit)发送和接收字节.而TTL.RS-232是指的电平标准(电信号). ...

  9. rs232接口_、 迪文串口屏TTL与主控板RS232电平信号转换方案

    迪文串口屏TTL与主控板RS232电平信号转换方案 一.TTL和RS232简述 串口.COM口是指的物理接口形式(硬件),按位(bit)发送和接收字节.而TTL.RS-232是指的电平标准(电信号). ...

最新文章

  1. 最后1周 | 高级转录组分析和R语言数据可视化第十一期 (报名线上课还可免费参加线下课)...
  2. 打马赛克就安全了吗?AI消除马赛克,GitHub开源项目上线三天收获近7000星
  3. JavaScript基础知识(函数)
  4. python爬虫工程师-Python爬虫工程师
  5. auto make System.map to C header file
  6. 对php专业的认识,对PHP要有个全面的认识
  7. 操作系统--第一章 绪论(408计算机考研)
  8. AssetsLibrary使用介绍
  9. Sql Server系列:键和约束
  10. Cannot add or update a child row: a foreign key constraint
  11. Docker安装宝塔没想到竟然如此之简单~
  12. python语言入门-Python语言入门.pdf
  13. vaex 处理海量数据_爱了爱了!0.052 秒打开 100GB 数据,这个Python开源库火爆了!...
  14. 阿里云服务器部署GeoServer以及跨域处理
  15. secoclient Linux安装
  16. 直播教学系统16项功能
  17. qwidget美化_Qt美化界面的心得整理
  18. ARM指令寻址方式及RealView MDK开发环境ARM汇编程序实践
  19. 【CMake 语法】(6) CMake 条件、循环、跳出循环
  20. Ollydbg使用技巧

热门文章

  1. Win11不会弹出外置硬盘怎么办?
  2. 北京昌平区专精特新中小企业申报流程
  3. 晶振噪声及杂散_什么是温补晶振?温补晶振的工作原理是什么?
  4. ssh 执行远程命令卡住问题解决
  5. Au 入门系列之九:多轨混音
  6. 2021-10-29
  7. 911和112成世界通用紧急呼叫电话号码
  8. nginx 正反向代理
  9. 重大通知!北京2020软考取消!合并到下一年度!
  10. 关于Sass和Less牵扯的问题