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

2023-05-16

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

  • Opencv+外置计算机摄像头。需要计算机作为上位机。
  • Stm32+OV7670。较难,大师级。
  • OpenMV摄像头。较简单,入门级。

博主刚开始为了准备项目,了解尝试过前两种方式,最后才终于接触到OpenMV这种主控板,因为其开发简单、结构简单、非常适合用于智能小车,入门虽然简单,功能却十分强大。

OpenMV简介:

OpenMV的目标是成为“机器视觉世界的Arduino ",有自己的IDE,采用Python二次开发简单易用,可扩展,开源,详细教程和技术手册。

OpenMV3是主要以STM32F427CPU为核心,集成了OV7725摄像头的模块。

OpenMV的功能:
颜色追踪、路线识别、形状识别、二维码识别、人脸识别、瞳孔追踪等。
12上图来源

入手准备:

  • 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+y
	return(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 = 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
#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 + n
    n = 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 的值为:", 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):

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

#类定义一个叫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

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

识别颜色例子:

# 色块监测例子 这个例子展示了如何通过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, 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!")

画圆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应该增加。

坐标和图像大小

设置图像大小
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(使用前将#替换为@)

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

  • OpenMV巡线

    你向别人介绍openmv就说哦这是一个嵌入式的机器视觉模块 一个摄像头模块带有主控 xff0c 可以用Python编程 用openMV巡线 借助的是线性回归 xff0c 线性回归的意思就是找出一条直线嘛 xff0c 用最小二乘法 xff0c
  • openmv与其他单片双向串口通信

    Openmv与其他单片双向串口通信 目的 为了让openmv进行阈值切换或者只运行某一部分代码 xff0c 因此需要openmv与其他单片建立双向通信进行更改内部参数 起因 openmv自带接收函数uart read 进行接收 xff0c
  • Openmv+STM32F103C8T6视觉巡线小车

    Openmv巡线 机器视觉巡线处理是参考openmv官方代码 Openmv官网源代码 xff1a book openmv cc project follow lines html 根据官网视频及教程将源码注入openmv中 小车巡的是黑线
  • OPENMV的学习(三)巡线

    存储文件 插入sd卡 xff0c 会将默认储存地址flash改为sd卡 image save span class token punctuation span span class token string 34 example jpg
  • pixhawk无人机结合openmv之精准降落

    pixhawk飞控与openmv之精准降落 一 精准降落概述二 精准降落流程三 代码逻辑流程四 总结反思改进 一 精准降落概述 1 概述 无人机在生产生活中逐渐获得更大的用途 xff0c 京东的物流无人机有望解决用户快递最后一分钟的问题 x
  • 学习OpenMV(一)详细参数及简单介绍

    目录 一 Open MV 简介 1 OpenMV摄像头的特点 xff1a 2 OpenMV摄像头的应用 xff1a 3 规格 xff1a 二 搭建环境 xff0c Open MV IDE安装 1 Windows系统 2 Linux系统 三
  • pid摄像头循迹(opencv和openmv)

    pid摄像头循迹 xff08 opencv和openmv xff09 用摄像头进行循迹的方法参考硬件选型方面软件思路一 图像预处理 xff1a 代码部分二 线性拟合opencv线性拟合 xff1a 实际在树莓派上运行时 xff0c 帧率也比
  • openmv的串口传输

    import sensor image time from pid import PID from pyb import Servo from pyb import UART uartCP 61 UART 1 115200 用于电脑与OPe
  • 【DIY】基于OpenMV的STM32追球小车

    目录 xff1a 总体设计1 基础硬件DIY设计1 xff09 整体原理图2 xff09 PCB电路 2 OpenMV简单识别程序设计 与 STM32控制程序设计1 xff09 OpenMV简单识别程序设计 microPython 2 xf
  • Openmv学习day2——AprilTag

    仅作为个人学习 xff0c 原文地址 xff1a 链接 link AprilTag的简介 AprilTag是一个视觉基准系统 xff0c 可用于各种任务 xff0c 包括AR xff0c 机器人和相机校准 这个tag可以直接用打印机打印出来
  • 【毕业设计】基于STM32及OpenMV的云台追踪装置

    目录 修改记录1 摘 要2 整体功能分析3 硬件选型3 1 OpenMV4 Cam H73 2 STM32F103ZET63 3 DS3120舵机3 4 LED补光板3 5 供电及稳压3 6 硬件连接 4 软件功能实现4 1 OpenMV部
  • 【串口通信】K210与STM32串口通信、K210与OpenMV串口通信

    串口通信 K210与STM32串口通信 K210与OpenMV串口通信 串口通信前言为何需要串口通信 K210如何进行串口通信K210串口配置K210串口发送相关定义K210串口发送测试K210串口接收相关定义K210串口接收测试 STM3
  • openmv探索_4_AprilTag标记追踪

    原理及代码 AprilTag标记追踪 空间坐标系的建立 以镜头中心为坐标系原点 xff0c 建立空间坐标系 图2 1 空间坐标系 旋转角度 xff08 参考系是上图中的坐标系 xff09 1 初始状态 图3 1 物体摆放的初始位置 上图的
  • OpenMV:21控制多个舵机(需要模块PCA9685)

    文章目录 连接代码控制单个舵机的旋转pc8596 pyservo pymain py利用两个舵机拓展板控制16个舵机 今天我们来学习下 OpenMV的舵机拓展板来控制多个舵机同时使用 如果我们想控制三个以上的舵机 xff0c 就需要用到舵机
  • OpenMV:23串口发送数据

    文章目录 产品Hello World简单的数据发送 本节讲解 如何使用OpenMV通过串口来发送数据 OpenMV 是可以直接通过串口发送字符串的 为什么要用串口呢 xff1f 因为要时候需要把信息传给其他MCU xff08 单片机 xff
  • OpenMv测距(Apriltag)

    利用OpenMv测离Apriltag的距离 xff08 其他色块啥的算法都差不多 xff0c 主要是Apriltag精确一些 xff09 span class token comment 本次利用OpenMv单目测距Apriltag离摄像头
  • OpenMV识别色块与STM2F4通过串口通信

    花了三天时间学习了一下OpenMV的简单使用 xff0c 在这写个博客记录一下 xff0c 并且上传自己的代码 xff0c 以方便交流学习 第一次发帖 xff0c 不周之处见谅 首先概括一下我实现的功能 xff1a OpenMV识别红色色块
  • OpenMV4开发笔记4-舵机控制

    OpenMV4的舵机控制脚有3个 P7 P8 P9 即可以控制3个舵机 Servo 1 gt P7 PD12 Servo 2 gt P8 PD13 OpenMV3 M7 OpenMV4 H7上增加 Servo 3 gt P9 PD14 注意
  • 毕业设计 单片机与OpenMV机器视觉目标跟踪系统

    文章目录 0 前言 课题简介 设计框架 3 openMV实现舵机定位色块STM32 3 硬件设计 4 软件设计 4 1 硬件连接 4 2 软件代码 OpenMV端 4 3 软件代码 STM32端 4 4 利用PC端测试数据数据是否发送接收正
  • 2021全国电设(F题)openmv的图像识别之数字识别

    基于openmv的图像识别 通过参加全国电子设计大赛F题总结出openmv4的数字识别 其它版本暂时没试过 欢迎交流 openmv简介 OpenMV是一个开源 低成本 功能强大的机器视觉模块 以STM32F427CPU为核心 集成了OV77

随机推荐