首页 > 其他分享 >【8月摸鱼计划】OpenMV寻找色块

【8月摸鱼计划】OpenMV寻找色块

时间:2023-08-23 11:32:34浏览次数:58  
标签:draw 色块 img blob 摸鱼 threshold 识别 sensor OpenMV

OpenMV的官方教程:寻找色块;single_color_rgb565_blob_tracking示例讲解;视频讲解


需要提前看的文章:程序烧录;颜色阈值设置


目录


threshold_index和thresholds解析


固定代码部分


死循环部分


clock.tick()讲解


sensor.snapshot()讲解


for ... in ...部分


image.find_blobs()函数讲解


blob.elongation()讲解


img.draw_edges()和 img.draw_line部分解析


img.draw_rectangle(blob.rect())解析。


print()解析


结论:


我们点击右上角文件——>示例——>OpenMV——>Color Tracking——>single_color_rgb565_blob_tracking,打开单颜色识别的代码。代码如下,我增加了中文注释,你打开的将会是英文的注释。


# 这个例子展示了使用OpenMV Cam的单色RGB565跟踪。

import sensor, image, time, math

threshold_index = 0 # 0 for red, 1 for green, 2 for blue

# 颜色跟踪阈值 (L Min, L Max, A Min, A Max, B Min, B Max)

# 下面的阈值通常跟踪红色/绿色/蓝色的东西。您可能希望调整它们……

thresholds = [(30, 100, 15, 127, 15, 127), # 通用的红色阈值

             (30, 100, -64, -8, -32, 32), # 通用的绿色阈值

             (0, 30, 0, 64, -128, 0)]     # 通用的蓝色阈值

sensor.reset()                      #重置感光元件,重置摄像机

sensor.set_pixformat(sensor.RGB565) #设置颜色格式为RGB565,彩色,每个像素16bit。

sensor.set_framesize(sensor.QVGA)   #图像大小为QVGA

sensor.skip_frames(time = 2000)     #跳过n张照片,在更改设置后,跳过一些帧,等待感光元件变稳定。

sensor.set_auto_gain(False)         #颜色识别必须关闭自动增益,会影响颜色识别效果

sensor.set_auto_whitebal(False)     #颜色识别必须关闭白平衡,会影响颜色识别效果,导致颜色的阈值发生改变

clock = time.clock()

# 只有像素大于“pixels_threshold”和面积大于“area_threshold”的区域才会

# 由下面的"find_blobs"返回。如果更改相机分辨率,则更改“pixels_threshold”和  

# “area_threshold”。"merge=True"合并图像中所有重叠的斑点。。

while(True):

   clock.tick()             # 追踪两个snapshots()之间经过的毫秒数.

   img = sensor.snapshot()  #截取感光元件中的一张图片

   #在img.find_blobs这个函数中,我们进行颜色识别

   #roi是“感兴趣区”,是在画面的中央还是右上方或者哪里进行颜色识别。此处我们没有进行配置,默认整个图像进行识别

   for blob in img.find_blobs([thresholds[threshold_index]], pixels_threshold=200, area_threshold=200, merge=True):

       # 这些值依赖于blob不是循环的-否则它们将不稳定。

       if blob.elongation() > 0.5:

           img.draw_edges(blob.min_corners(), color=(255,0,0))     #利用一个红色的方框,绘制出Blob的最小边界

           img.draw_line(blob.major_axis_line(), color=(0,255,0))  #利用一个绿色的线,绘制穿过最小面积矩形的最长边

           img.draw_line(blob.minor_axis_line(), color=(0,0,255))  #利用一个蓝色的线,绘制穿过最小面积矩形的最短边

       # 这些值始终是稳定的。

       img.draw_rectangle(blob.rect())      #用矩形标记出目标颜色区域

       img.draw_cross(blob.cx(), blob.cy()) #在目标颜色区域的中心画十字形标记

       # 注意- blob的旋转是唯一的0-180。

       img.draw_keypoints([(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=20)

   print(clock.fps()) #打印帧率,可在OpenMV IDE的左下角串行终端查看

threshold_index和thresholds解析

threshold_index:设置要识别的颜色值,示例中的0表示识别红色,1识别绿色,2识别蓝色。


thresholds:存放可能要识别物体的LAB阈值。此处分别是红色,绿色,蓝色的阈值


threshold_index = 0 # 0 for red, 1 for green, 2 for blue

# 颜色跟踪阈值 (L Min, L Max, A Min, A Max, B Min, B Max)

# 下面的阈值通常跟踪红色/绿色/蓝色的东西。您可能希望调整它们……

thresholds = [(30, 100, 15, 127, 15, 127), # 通用的红色阈值

             (30, 100, -64, -8, -32, 32), # 通用的绿色阈值

             (0, 30, 0, 64, -128, 0)]     # 通用的蓝色阈值

固定代码部分

以下是固定代码,没什么好讲的。只需要注意,因为我们是颜色识别,所以必须关闭白平衡和自动增益。如果不关闭会导致颜色阈值发生改变,影响识别效果。感光元件介绍,这是官方介绍。RGB565表示是彩色识别,GRAYSCALE是黑白的。set_framesize是设置图像大小。


sensor.reset()                      #重置感光元件,重置摄像机

sensor.set_pixformat(sensor.RGB565) #设置颜色格式为RGB565,彩色,每个像素16bit。

sensor.set_framesize(sensor.QVGA)   #图像大小为QVGA

sensor.skip_frames(time = 2000)     #跳过n张照片,在更改设置后,跳过一些帧,等待感光元件变稳定。

sensor.set_auto_gain(False)         #颜色识别必须关闭自动增益,会影响颜色识别效果

sensor.set_auto_whitebal(False)     #颜色识别必须关闭白平衡,会影响颜色识别效果,导致颜色的阈值发生改变

clock = time.clock()


死循环部分

进入死循环


while(True):

clock.tick()讲解

clock.tick() ,OpenMV官方文档的解释是开始追踪运行时间。我将其注释掉也可以正常运行。应该就只是记录OpenMV运行时间而已,返回值并没有接收,可有可无。


clock.tick()             # 追踪两个snapshots()之间经过的毫秒数.

sensor.snapshot()讲解

img = sensor.snapshot(),截取感光元件中的照片,将截取的图片存入辅助帧缓冲存储区,返回参数image对象。这个时候,img这个变量就是image,可以理解为等价。


img = sensor.snapshot()#截取感光元件中的一张图片

for ... in ...部分

image.find_blobs()函数讲解

这个for ... in ...,我们先看img.find_blobs。前面说了,这个时候,img这个变量就是image。也就是说img.find_blobs=image.find_blobs。我们查官方手册查看此函数内容,可以看到第一个参数thresholds表示颜色阈值,也就是上面我们自己设置的LAB值。


第二个参数是roi,感兴趣区,通俗来说就是,我们要在画面中的哪一部分进行颜色识别。此处没有设置,就表面是整个区域都要进行颜色识别。


第三,四个参数是x_stride ,y_stride 。表示x和y轴上像素点个数大于等于x_stride和y_stride才会被识别。比如说, x_stride=2, y_stride=1是默认参数,此处这里没有设置,系统就认定X轴像素点不能小于2个。如果识别到x和y轴仅有一个像素点宽度,将会被忽略。


第五个参数是invert, 反转阈值,把阈值以外的颜色作为阈值进行查找。意思就是说,如果invert=True,而我们设置的颜色阈值是红色。那么OpenMV将会识别除红色以外的所有区域。


第六,七个参数分别是area_threshold (面积阈值),pixels_threshold (像素个数阈值)。如果如果色块被框起来的面积小于area_threshold,或者色块像素数量小于pixels_threshold,会被过滤掉。


第八个参数是merge 。默认为False,如果merge=True,那么识别到的所有色块将会合并成一个大色块。例如,OpenMV识别到右上方,中间分别一个色块(注:两个没有连接,具有明显的距离)。如果merge=False,那么图像上将会出现两个方框。而如果merge=True,那么将会是一个大方框将两个方框都包含。


第九个参数margin ,如果设置为1,那么两个blobs如果间距1一个像素点,也会被合并。通俗来说就是,如果左边a个像素点,右边b个像素点,这两个都被识别。但是a和b中间有一个像素点不属于识别单位,因为margin=1,我们会将这一个不是识别单位强行变成识别单位。但是假如a和b之间有两个像素点不属于识别单位,这样着两个像素点就不会被强行变成识别单位。


之后的四个参数我也没搞明白,默认参数就行,不用管。


此处,我们对这个img.find_blobs传入了四个值,分别是目标LAB阈值,目标像素个数低于200个的忽略,被框选面积小于200也被忽略。具体值可以根据需求调整。识别到的所有色块将会合并成一个大色块。(注意,如果我们不是按照规定的顺序给函数传入参数,必须前面加参数类型=传入值。如,thresholds[threshold_index]就是第一个参数值,所以不需要写成thresholds=[thresholds[threshold_index]],而后面三个需要,因为他们具体传参不是在第二,三,四位置)


之后img.find_blobs这个函数会根据传入参数进行输出一个包括每个色块的色块对象的列表,此列表存入blob中。


for blob in img.find_blobs([thresholds[threshold_index]], pixels_threshold=200, area_threshold=200, merge=True):

# 如果我们需要配置感兴趣区,方法如下。roi的格式是(x, y, w, h)的tupple.

# x:ROI区域中左上角的x坐标

# y:ROI区域中左上角的y坐标

# w:ROI的宽度

# h:ROI的高度

left_roi = [0,0,160,240]  

blobs = img.find_blobs([red],roi=left_roi)

blob.elongation()讲解

后面这句if blob.elongation() > 0.5:,blob.elongation()这个函数的作用就是看这个图案是否像圆形,如果越像圆,这个值越小,越不像圆,这个值越大。




if blob.elongation() > 0.5:  #可忽略

img.draw_edges()和 img.draw_line部分解析

接下来这三句话也可以注释,因为我们只需要把目标框选出来就可以了。这三句话作用就是利用一个红色的方框,绘制出Blob的最小边界。利用一个绿色的线,绘制穿过最小面积矩形的最长边。利用一个蓝色的线,绘制穿过最小面积矩形的最短边。如果我这么说不理解,可以分别注释掉着三句话,查看OpenMV的反应,就能理解了。


           img.draw_edges(blob.min_corners(), color=(255,0,0))     #利用一个红色的方框,绘制出Blob的最小边界

           img.draw_line(blob.major_axis_line(), color=(0,255,0))  #利用一个绿色的线,绘制穿过最小面积矩形的最长边

           img.draw_line(blob.minor_axis_line(), color=(0,0,255))  #利用一个蓝色的线,绘制穿过最小面积矩形的最短边

img.draw_rectangle(blob.rect())解析。

img.draw_rectangle(blob.rect())就是利用矩形将目标单位框选出来。blob.rect(),返回一个色块边界框,矩形元组(x, y, w, h) ,对应左上角x,y坐标,矩形宽和高。image.draw_rectangle(),利用(x, y, w, h) 绘制矩形,颜色默认为白色。


blob.cx(), blob.cy()分别返回色块中心点的x,有坐标。利用 img.draw_cross()绘制一个十字形标记。

       img.draw_rectangle(blob.rect())      #用矩形标记出目标颜色区域

       img.draw_cross(blob.cx(), blob.cy()) #在目标颜色区域的中心画十字形标记

print()解析

最后这句就是打印帧率(帧率是每秒图像的数量)。如果只想用于颜色识别,可注释掉。


   print(clock.fps()) #打印帧率

结论:

最后结果如下,可删除注释部分


# 这个例子展示了使用OpenMV Cam的单色RGB565跟踪。

import sensor, image, time, math

threshold_index = 0 # 0 for red, 1 for green, 2 for blue

# 颜色跟踪阈值 (L Min, L Max, A Min, A Max, B Min, B Max)

# 下面的阈值通常跟踪红色/绿色/蓝色的东西。您可能希望调整它们……

thresholds = [(16, 8, -39, 18, -31, 9), # generic_red_thresholds

             (54, 77, -9, 9, 85, 47), # generic_green_thresholds

             ]     # generic_blue_thresholds

sensor.reset()#重置感光元件,重置摄像机

sensor.set_pixformat(sensor.RGB565) #设置颜色格式为RGB565,彩色,每个像素16bit。

sensor.set_framesize(sensor.QVGA)   #图像大小为QVGA

sensor.skip_frames(time = 2000)     #跳过n张照片,在更改设置后,跳过一些帧,等待感光元件变稳定。

sensor.set_auto_gain(False)         #颜色识别必须关闭自动增益,会影响颜色识别效果

sensor.set_auto_whitebal(False)     #颜色识别必须关闭白平衡,会影响颜色识别效果,导致颜色的阈值发生改变

clock = time.clock()

# 只有像素大于“pixels_threshold”和面积大于“area_threshold”的区域才是

# 由下面的"find_blobs"返回。更改“pixels_threshold”和“area_threshold”

# 相机的分辨率。"merge=True"合并图像中所有重叠的斑点。

while(True):

   clock.tick()# 追踪两个snapshots()之间经过的毫秒数.

   img = sensor.snapshot()#截取感光元件中的一张图片

   #在img.find_blobs这个函数中,我们进行颜色识别

   #roi是“感兴趣区”,是在画面的中央还是右上方或者哪里进行颜色识别。此处我们没有进行配置,默认整个图像进行识别

   for blob in img.find_blobs([thresholds[threshold_index]], pixels_threshold=200, area_threshold=200, merge=True):

       # 这些值依赖于blob不是循环的-否则它们将不稳定。

       #if blob.elongation() > 0.5:

           #img.draw_edges(blob.min_corners(), color=(255,0,0))    #利用一个红色的方框,绘制出Blob的最小边界

           #img.draw_line(blob.major_axis_line(), color=(0,255,0)) #利用一个绿色的线,绘制穿过最小面积矩形的最长边

           #img.draw_line(blob.minor_axis_line(), color=(0,0,255)) #利用一个蓝色的线,绘制穿过最小面积矩形的最短边

       # 这些值始终是稳定的。

       img.draw_rectangle(blob.rect())      #用矩形标记出目标颜色区域

       img.draw_cross(blob.cx(), blob.cy()) #在目标颜色区域的中心画十字形标记

       # 注意- blob的旋转是唯一的0-180。

       #img.draw_keypoints([(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=20)

   #print(clock.fps()) #打印帧率



标签:draw,色块,img,blob,摸鱼,threshold,识别,sensor,OpenMV
From: https://blog.51cto.com/u_15784394/7200584

相关文章

  • 【8月摸鱼计划】看完这篇,请不要再说不懂MOSFET!
    功率半导体器件在工业、消费、军事等领域都有着广泛应用,具有很高的战略地位,下面我们从一张图看功率器件的全貌:功率半导体器件又可根据对电路信号的控程度分为全型、半控型及不可;或按驱动电路信号性质分为电压驱动型、电流驱动型等划分类别电流驱动型等划分类别电流驱动型......
  • 【8月摸鱼计划】python不支持的数据类型
    python不支持的数据类型是:char、byte类型。python支持的数据类型有:文本类型:str数值类型:int,float,complex序列类型:list,tuple,range映射类型:dict集合类型:set,frozenset布尔类型:bool二进制类型:bytes,bytearray,memoryview......
  • 【8月摸鱼计划】linux修改主机名
    linux通过修改配置文件/etc/sysconfig/network的HOSTNAME对应的值,可实现修改主机名。[root@localhost~]#vi/etc/sysconfig/networkNETWORKING=yesHOSTNAME=localhost.localdomaintext如:把localhost.localdomain改为其他名字。更新hosts文件[root@localhost~]#vi/etc/hosts......
  • 【8月摸鱼计划】网页证书过期怎么办
    网页证书过期怎么办有些浏览器在访问某些网站时会出现证书错误过期的情况,此时只要是涉及到输入账户密码的网页都无法打开,真是一件让人苦恼的事情,到底网页证书过期怎么办呢?下面介绍两种方法来解决网页证书过期的问题。一、计算机中的日期和时间不同步网页证书过期解决方法:......
  • 【8月摸鱼计划】电脑证书失效,导致无法上网
    电脑证书失效怎么办?如果您的电脑证书失效,导致无法上网,您可以尝试以下步骤来解决问题:1.检查网络连接:检查您的网络连接是否正常,尝试重新启动路由器或调整网络设置。2.检查DNS服务器配置:检查计算机或网络设备的DNS服务器设置是否正确,确保使用的DNS服务器可用并已正确配置。您可以尝......
  • 【8月摸鱼计划】Air780E、Luat开发平台、对应的lib库的问题
      Air780E是一款基于Luat开发平台的模组,支持LuatIDE进行任务开发。LuatIDE是专为Luat开发平台设计的集成开发环境,方便开发者进行代码编写、调试和下载。关于找不到对应的lib库的问题,可能是由于以下几个原因:1.库文件未导入:确保正确安装LuatIDE,并在项目中导入相应的库文件......
  • 【8月摸鱼计划】电脑32位安装64 位注意事项
    在电脑上安装32位操作系统时,有几个注意事项需要考虑:1.确认硬件兼容性:在安装32位操作系统之前,首先要确保计算机硬件兼容32位架构。大多数计算机都支持32位操作系统,但如果你的计算机非常老旧或者特殊配置,可能会存在不兼容的情况。2.了解软件兼容性:部分较新的软件可能只支持64位操......
  • [8月摸鱼计划] Vscode使用
    VSCode(VisualStudioCode)是一款由Microsoft开发的跨平台的轻量级集成开发环境(IDE),它广泛用于编写、调试和运行各种编程语言的代码。使用VSCode可以有以下步骤:下载与安装:在VSCode官方网站上下载适合你操作系统的安装包,并按照提示进行安装。启动VSCode:安装完成后,点击桌面图标......
  • 【8月摸鱼计划】剪映的底层原理
    剪映是一款视频编辑软件,其底层原理处理和音频处理等多个方面。1.视频处理:剪映的底层实现了视频的导入、裁剪、拼接、调整速度、添加特效、应用滤镜等功能。在视频处理过程中,剪映会对视频进行解码、帧间差分、帧率控制、编码等操作,以达到用户所需的编辑效果。2.图像处理:剪映提供......
  • daimayuan252 | 摸鱼(状压, 枚举, 小技巧)
    题目很straightforward的,看到n范围很小考虑状压,暴力枚举所有的可能pattern.第一种做法,暴力枚举是\(O(2^n)\)的,然后check函数判断是\(O(n^2)\)的,一共是\(O(n^22^n)\)的,可以通过.第二种做法,我们考虑把判断pattern是否合法的限制条件也压成二进制串,那么我们比对条......