OpenMV入门介绍
创始人
2025-05-30 22:45:02

这里写目录标题

  • 一、OpenMV是什么
  • 二、OpenART mini与OpenMV对比
  • 三、图像处理背景知识
    • 1.像素和分辨率
    • 2. 帧率
    • 3.RGB三原色
    • 4.LAB颜色空间
  • 四、OpenMV图像处理方法
    • 1.感光元件
        • 自动增益/白平衡/曝光
        • 窗口ROI
    • 2.画图
        • 画线
        • 画框
        • 画圆
        • 画十字
        • 写字
        • 示例
    • 3. 寻找色块(颜色识别)
        • find_blobs()函数
        • find_blobs()返回值
        • 示例
    • 4. 测距
  • 四、串口通道
  • 五、条形码、矩形码、二维码
    • 1.条形码
    • 2.矩形码
    • 3.二维码

一、OpenMV是什么

  OpenMV是一款具有图像处理功能的可编程摄像头模块,可以实现简单的机器视觉应用,例如人脸检测、Apriltag追踪、圆形检测、矩形检测等。

二、OpenART mini与OpenMV对比

  (这里介绍另一款可编程摄像头模块OpenART mini,在功能上与OpenMV几乎无差别,但性能和价格都优于OpenMV)
  OpenART mini是逐飞科技恩智浦的OpenART套件的基础上,去除非视觉部分而制作出来的迷你版。虽说只是迷你版,但“麻雀虽小,五脏俱全”。OpenART mini 不仅可以很轻松的完成机器视觉应用,还可以完成神经网络模型的部署。

比较项目OpenMV4 H7 PlusOpenART mini
价格599380
处理器STM32H743IIMIMXRT1064
主频480MHz600MHz
RAM1M1M
FLASH2M4M
编程环境MicropythonMicropython
OpenMV视觉库

三、图像处理背景知识

1.像素和分辨率

  • 像素:像素是数字图像中的最小单元

  • 分辨率:分辨率指单位长度内像素点的数量,常用的度量为ppi(pixels per inch),即每英寸有多少像素点。

  感光元件是由很多个感光点构成的,比如有640×480640×480640×480个点,每个点就是一个像素,把每个点的像素收集整理起来,就是一副图片,那么这张图片的分辨率就是640×480640×480640×480:

在这里插入图片描述

2. 帧率

  帧率(FPS,Frames Per Second)就是每秒钟处理的图片数量,如果超过20帧,人眼就基本分辨不出卡顿。电影的帧率一般是24FPS,游戏的帧率一般都大于30FPS。

3.RGB三原色

  RGB指的是红绿蓝三种颜色,是光学三原色,所有的颜色都可以由这三种色彩混合而成。(三原色是依据人类视觉定义的,不存在绝对的三原色)

4.LAB颜色空间

  Lab是由一个亮度通道和两个颜色通道组成的。在Lab颜色空间中,每个颜色用L、a、b三个数字表示,各个分量的含义是这样的:

  • L 代表亮度
  • a 代表从绿色到红色的分量
  • b 代表从蓝色到黄色的分量

  Lab是基于人对颜色的感觉来设计的,更具体地说,它是感知均匀(perceptual uniform)的。Perceptual uniform的意思是,如果数字(即前面提到的L、a、b这三个数)变化的幅度一样,那么它给人带来视觉上的变化幅度也差不多。

  Lab相较于RGB与CMYK等颜色空间更符合人类视觉,也更容易调整:想要调节亮度就调节L通道,想要调节色彩平衡就分别调ab

四、OpenMV图像处理方法

1.感光元件

  OpenMV中使用sensor模块来设置感光元件的参数,具体使用方法如下:

import sensor#引入感光元件的模块# 设置摄像头
sensor.reset()#初始化感光元件
sensor.set_pixformat(sensor.RGB565)#设置为彩色
sensor.set_framesize(sensor.QVGA)#设置图像的大小
sensor.skip_frames()#跳过n张照片,在更改设置后,跳过一些帧,等待感光元件变稳定。# 一直拍照
while(True):img = sensor.snapshot()#拍摄一张照片,img为一个image对象

自动增益/白平衡/曝光

  • sensor.set_auto_gain()
    自动增益开启(True)或者关闭(False)。在使用颜色追踪时,需要关闭自动增益。
  • sensor.set_auto_whitebal()
    自动白平衡开启(True)或者关闭(False)。在使用颜色追踪时,需要关闭自动白平衡。
  • sensor.set_auto_exposure(enable[, exposure_us])
    • enable 打开(True)或关闭(False)自动曝光。默认打开。
    • 如果 enable 为 False,则可以用 exposure_us 设置一个固定的曝光时间(以微秒为单位)。

窗口ROI

  ROI:Region Of Interest,图像处理中的术语“感兴趣区”。就是在要处理的图像中提取出的要处理的区域。

  • sensor.set_windowing(roi)
    roi的格式是(x, y, w, h)
    • x:ROI区域中左上角的x坐标
    • y:ROI区域中左上角的y坐标
    • w:ROI的宽度
    • h:ROI的高度

2.画图

  视觉系统通常需要给使用者提供一些反馈信息。直接在图像中显示出来,很直观。

画线

  • image.draw_line(line_tuple, color=White)
    在图像中画一条直线。
    • line_tuple的格式是(x0, y0, x1, y1),意思是(x0, y0)到(x1, y1)的直线。
    • 颜色可以是灰度值(0-255),或者是彩色值(r, g, b)的tupple。默认是白色

画框

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

画圆

  • 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_string(x, y, text, color=White)
    在图像中写字 8x10的像素
    • x,y是坐标。
    • text是要写的字符串。

示例

# 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!")

在这里插入图片描述

3. 寻找色块(颜色识别)

  OpenMV通过find_blobs()函数可以找到色块(带颜色的物体),返回色块的位置、高度、像素等信息。

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是颜色的阈值,在返回的色块对象blob可以调用code方法,来判断是什么颜色的色块。
    • x_stride(查找的色块的x方向上最小宽度的像素,默认为2)
    • y_stride(查找的色块的y方向上最小宽度的像素,默认为1)
    • invert(反转阈值,把阈值以外的颜色作为阈值进行查找)
    • area_threshold(面积阈值,如果色块被框起来的面积小于这个值,会被过滤掉)
    • pixels_threshold(像素个数阈值,如果色块像素数量小于这个值,会被过滤掉)
    • merge(合并,如果设置为True,那么合并所有重叠的blob为一个)
      注意:这会合并所有的blob,无论是什么颜色的。如果你想混淆多种颜色的blob,只需要分别调用不同颜色阈值的find_blobs。
    • margin(边界,如果设置为1,那么两个blobs如果间距1一个像素点,也会被合并)

find_blobs()返回值

  • for blob in img.find_blobs(thresholds):

    • blob.rect() 返回这个色块的外框——矩形元组(x, y, w, h)
    • blob.x() 返回色块的外框的x坐标(int)
    • blob.y() 返回色块的外框的y坐标(int)
    • blob.w() 返回色块的外框的宽度w(int)
    • blob.h() 返回色块的外框的高度h(int)
    • blob.pixels() 返回色块的像素数量(int)
    • blob.cx() 返回色块的外框的中心x坐标(int)
    • blob.cy() 返回色块的外框的中心y坐标(int)
    • blob.rotation() 返回色块的旋转角度(单位为弧度)(float)
    • blob.code() 返回一个16bit数字,每一个bit会对应每一个阈值
    • blob.count() 如果merge=True,那么就会有多个blob被合并到一个blob,这个函数返回的就是这个的数量
    • blob.area() 返回色块的外框的面积
    • blob.density() 返回色块的密度

示例

# Single Color RGB565 Blob Tracking Example
#
# This example shows off single color RGB565 tracking using the OpenMV Cam.import sensor, image, time, maththreshold_index = 0 # 0 for red, 1 for green, 2 for blue# Color Tracking Thresholds (L Min, L Max, A Min, A Max, B Min, B Max)
# The below thresholds track in general red/green/blue things. You may wish to tune them...
thresholds = [(30, 100, 15, 127, 15, 127), # generic_red_thresholds(30, 100, -64, -8, -32, 32), # generic_green_thresholds(0, 30, 0, 64, -128, 0)] # generic_blue_thresholdssensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
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()# Only blobs that with more pixels than "pixel_threshold" and more area than "area_threshold" are
# returned by "find_blobs" below. Change "pixels_threshold" and "area_threshold" if you change the
# camera resolution. "merge=True" merges all overlapping blobs in the image.while(True):clock.tick()img = sensor.snapshot()for blob in img.find_blobs([thresholds[threshold_index]], pixels_threshold=200, area_threshold=200, merge=True):# These values depend on the blob not being circular - otherwise they will be shaky.if blob.elongation() > 0.5:img.draw_edges(blob.min_corners(), color=(255,0,0))img.draw_line(blob.major_axis_line(), color=(0,255,0))img.draw_line(blob.minor_axis_line(), color=(0,0,255))# These values are stable all the time.img.draw_rectangle(blob.rect())img.draw_cross(blob.cx(), blob.cy())# Note - the blob rotation is unique to 0-180 only.img.draw_keypoints([(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=20)print(clock.fps())

4. 测距

  OpenMV采用的是单目摄像头,想要实现测距,就需要选参照物,利用参照物的大小比例来计算距离。

# Measure the distance
#
# This example shows off how to measure the distance through the size in imgage
# This example in particular looks for yellow pingpong ball.import sensor, image, time# For color tracking to work really well you should ideally be in a very, very,
# very, controlled enviroment where the lighting is constant...
yellow_threshold   = ( 56,   83,    5,   57,   63,   80)
# You may need to tweak the above settings for tracking green things...
# Select an area in the Framebuffer to copy the color settings.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.K=5000#the value should be measuredwhile(True):clock.tick() # Track elapsed milliseconds between snapshots().img = sensor.snapshot() # Take a picture and return the image.blobs = img.find_blobs([yellow_threshold])if len(blobs) == 1:# Draw a rect around the 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/Lmprint(length)#print(clock.fps()) # Note: Your OpenMV Cam runs about half as fast while# connected to your computer. The FPS should increase once disconnected.

四、串口通道

  在项目中,OpenMV通常只用来处理图像数据,而处理结果要传到MCU中做下一步处理。这个过程中需要用到串口来传送数据。

from machine import UART
uart = UART(1, baudrate=115200)     # 初始化串口 波特率设置为115200 TX是B12 RX是B13
uart.write("uart test\r\n")         # 发送字符串
uart_num = 0                        # 定义一个变量
uart_array = [48,49,50,51,52,53,54,55,56,57]  # 定义一个列表 保存数字
uart.write(bytearray(uart_array))   # 发送列表
uart.write(bytearray([0x41]))       # 发送一个十六进制数据
while(True):uart_num = uart.any()       # 获取当前串口数据数量if(uart_num):uart_str = uart.read(uart_num) # 读取串口数据uart.write(uart_str)    # 将读取到的串口数据发回# uart.read会自动在数据末尾添加\n的操作,如果想去掉可以用strip()去掉# 例如 uart_str = uart.read(uart_num).strip()# 这样 uart_str得到的数据就不会被自动添加\n

五、条形码、矩形码、二维码

1.条形码

  • find_barcodes([roi])
    查找 roi 内所有一维条形码并返回一个 image.barcode 对象列表
# 条形码识别例程
#
# 这个例子展示了使用OpenMV Cam M7来检测条形码是多么容易。条形码检测不适用于M4相机。import sensor, image, time, mathsensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.VGA) # High Res!
sensor.set_windowing((640, 80)) # V Res of 80 == less work (40 for 2X the speed).
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)  # 必须关闭此功能,以防止图像冲洗…
sensor.set_auto_whitebal(False)  # 必须关闭此功能,以防止图像冲洗…
clock = time.clock()# 条形码检测可以在OpenMV Cam的OV7725相机模块的640x480分辨率下运行。
# 条码检测也将在RGB565模式下工作,但分辨率较低。 也就是说,
# 条形码检测需要更高的分辨率才能正常工作,因此应始终以640x480的灰度运行。def barcode_name(code):if(code.type() == image.EAN2):return "EAN2"if(code.type() == image.EAN5):return "EAN5"if(code.type() == image.EAN8):return "EAN8"if(code.type() == image.UPCE):return "UPCE"if(code.type() == image.ISBN10):return "ISBN10"if(code.type() == image.UPCA):return "UPCA"if(code.type() == image.EAN13):return "EAN13"if(code.type() == image.ISBN13):return "ISBN13"if(code.type() == image.I25):return "I25"if(code.type() == image.DATABAR):return "DATABAR"if(code.type() == image.DATABAR_EXP):return "DATABAR_EXP"if(code.type() == image.CODABAR):return "CODABAR"if(code.type() == image.CODE39):return "CODE39"if(code.type() == image.PDF417):return "PDF417"if(code.type() == image.CODE93):return "CODE93"if(code.type() == image.CODE128):return "CODE128"while(True):clock.tick()img = sensor.snapshot()codes = img.find_barcodes()for code in codes:img.draw_rectangle(code.rect())print_args = (barcode_name(code), code.payload(), (180 * code.rotation()) / math.pi, code.quality(), clock.fps())print("Barcode %s, Payload \"%s\", rotation %f (degrees), quality %d, FPS %f" % print_args)if not codes:print("FPS %f" % clock.fps())

2.矩形码

# 矩形码识别例程
#
# 这个例子展示了使用OpenMV Cam M7来检测数据矩阵是多么容易。数据矩阵检测不适用于M4相机。import sensor, image, time, mathsensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
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()img.lens_corr(1.8) # 1.8的强度对于2.8mm的镜头来说是好的。matrices = img.find_datamatrices()for matrix in matrices:img.draw_rectangle(matrix.rect(), color = (255, 0, 0))print_args = (matrix.rows(), matrix.columns(), matrix.payload(), (180 * matrix.rotation()) / math.pi, clock.fps())print("Matrix [%d:%d], Payload \"%s\", rotation %f (degrees), FPS %f" % print_args)if not matrices:print("FPS %f" % clock.fps())

3.二维码

# 二维码例程
#
# 这个例子展示了OpenMV Cam使用镜头校正来检测QR码的功能(请参阅qrcodes_with_lens_corr.py脚本以获得更高的性能)。
import sensor, image, timesensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)  # 必须关闭此功能,以防止图像冲洗…
clock = time.clock()while(True):clock.tick()img = sensor.snapshot()img.lens_corr(1.8) # 1.8的强度参数对于2.8mm镜头来说是不错的。for code in img.find_qrcodes():img.draw_rectangle(code.rect(), color = (255, 0, 0))print(code)print(clock.fps())

参考文章
OpenMV嵌入式图像处理

彻底搞懂Lab 颜色空间

相关内容

热门资讯

今日起招股发售价9.75港元,... 6月2日,车来了母公司元光科技启动全球发售,发售价9.75港元,预计将在6月10日在港交所挂牌。元光...
港股午评:恒生指数跌2.20%... 新京报贝壳财经讯 6月2日,港股午间收盘,恒生指数跌2.20%,恒生科技指数跌2.43%。石药集团跌...
夏乐:美债压力与美元走弱 全球... 原创 财联社 蜂网专家2025年05月29日《首席说》是财联社倾力打造的一档高端直播联线栏目。面向泛...
罗志恒:财政政策不应受3%赤字... 罗志恒系粤开证券首席经济学家、中国首席经济学家论坛理事自2008年以来,本轮积极财政政策实行了长达1...
三大利空,突袭! 三大利空,突... 时局依然不稳!今天早上,全球市场全线杀跌。日经指数一度杀跌近1.5%,中国台湾股指大跌近1%,港股三...
美国客户“疯狂”催单 这家川企... 自硬公司的精密零件产品之一:随钻用核心零部件。韩吉尔摄 “5月中旬,美国休斯敦的客户发邮件,要求尽快...
这只港股,突然暴涨超60%!发... 6月2日,亚太股市开盘后持续走弱。不过,港股方面,加密货币数字概念股大涨,连连数字涨62.67%。港...
招商基金三首席同日上任!“去管... 当同行纷纷为投研人才做“去管理化”减法时,招商基金却反其道而行之,提拔朱红裕、王景两位基金经理。这究...
2025浙江国际电子商务博览会... 这个周末,端午的粽叶飘香和六一小朋友的欢笑声撞了个满怀~跨境电商圈也跟着热闹到飞起。 从节令美食到文...
头部餐饮,火拼儿童餐 头部餐饮... 总第4234期作者 |餐饮老板内参内参君儿童餐,卷入next level端午恰逢六一,双节叠加背景下...
舆论战升级!巨子生物深夜回应,... 2025.06.02本文字数:2490,阅读时长大约4分钟作者 |第一财经 刘晓颖重组胶原蛋白成分之...
财经时评|以创新厚度重塑汽车产... 作者 远山中国汽车工业协会与工业和信息化部近期针对行业“内卷式”竞争的联合发声,为持续蔓延的价格战按...
恒生指数午盘下跌2.20%,恒... 6月2日午盘,香港恒生指数下跌2.20%,报22778.45点;恒生科技指数下跌2.43%,报504...
“以旧换新”带货1万亿,中国何... “美国想让制造业回流成为中国的样子,一个踏实劳作的‘生产者社会’;而中国想努力扩大消费成为美国的样子...
恒指半日跌2.2% 恒指半日跌... 【恒指半日跌2.2%】截至午间收盘,香港恒生指数下跌2.20%,报22778.45点;恒生科技指数下...
“成分之争”舆论战升级,巨子生... 重组胶原蛋白成分之争的舆论战再度升级。美妆博主 "大嘴博士" (郝宇)近日连续发文质疑,巨子生物(0...
汇川技术新注册《InoCube... 证券之星消息,近日汇川技术(300124)新注册了《InoCube-InoData数据分析系统V1....
博将控股多家所投企业荣登202... 博将控股多家所投企业荣登2025杭州独角兽与准独角兽榜单 2025年4月24日,由民建浙江省委会、浙...
刚刚,A50直线跳水!亚太股市... 6月2日,亚太股市开盘后持续走弱。富时中国A50期货开盘跌0.6%,截至目前跌幅1.91%。 截至...
问界、智界、享界、尊界,202... 2025鸿蒙智行:四界表现鸿蒙智行作为国内造车新势力的主流品牌,一共规划了“五界”车型,包括:问界、...
花样年控股:重组支持协议的最后... 6月1日,花样年控股(01777.HK)公告称,公司2024年4月29日所订立的重组支持协议的最终截...
蜜雪集团股价创上市以来新高 蜜... 新京报贝壳财经讯 6月2日,港股蜜雪集团盘中涨超7%,股价刷新上市新高。
美单边关税让全球经济面临更大不... 美国征收关税的对象和标准可能随意变更,其关税政策具有不可预测性。无论是外国企业,还是美国本土企业,都...
桃李面包创始人向其两儿子转让3... 5月30日晚间,桃李面包(沪市代码:603866)公告称,公司控股股东及实际控制人吴志刚通过大宗交易...
前4月东莞重大项目完成投资42... 本期看点:前4月东莞重大项目完成投资429.09亿元;长联科技募投项目提升年产至2.77万吨;广东省...
恒生指数跌幅扩大至2%,医药、... 6月2日,恒生指数跌幅扩大至2%,医药、地产、能源板块跌幅居前,美中嘉和跌超14%,石四药集团跌近1...
港股、A50飘绿,亚太市场多数... 早间,亚太市场多数下跌。港股、A50集体下跌其中,恒生指数、恒生科技指数开盘跌幅扩大, 港股生物技术...
雷军看好的两兄弟,要IPO了 ... 2021年夏,小米产业园办公室内,雷军饶有兴致地打量眼前一对兄弟,“为什么张波是创始人,董事长却是张...
圣阳股份涨1.66%,成交额9... 5月30日,圣阳股份涨1.66%,成交额9.82亿元,换手率15.03%,总市值66.67亿元。 异...