OpenMV的官方教程:寻找色块;single_color_rgb565_blob_tracking示例讲解;视频讲解
目录
img.draw_edges()和 img.draw_line部分解析
img.draw_rectangle(blob.rect())解析。
我们点击右上角文件——>示例——>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:设置要识别的颜色值,示例中的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() ,OpenMV官方文档的解释是开始追踪运行时间。我将其注释掉也可以正常运行。应该就只是记录OpenMV运行时间而已,返回值并没有接收,可有可无。
clock.tick() # 追踪两个snapshots()之间经过的毫秒数.
img = sensor.snapshot(),截取感光元件中的照片,将截取的图片存入辅助帧缓冲存储区,返回参数image对象。这个时候,img这个变量就是image,可以理解为等价。
img = sensor.snapshot()#截取感光元件中的一张图片
这个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)
后面这句if blob.elongation() > 0.5:,blob.elongation()这个函数的作用就是看这个图案是否像圆形,如果越像圆,这个值越小,越不像圆,这个值越大。

if blob.elongation() > 0.5: #可忽略
接下来这三句话也可以注释,因为我们只需要把目标框选出来就可以了。这三句话作用就是利用一个红色的方框,绘制出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())就是利用矩形将目标单位框选出来。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(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()) #打印帧率
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
如何使用Ruby的默认Curses库获取颜色?所以像这样:puts"\e[0m\e[30;47mtest\e[0m"效果很好。在浅灰色背景上呈现漂亮的黑色。但是这个:#!/usr/bin/envrubyrequire'curses'Curses.noecho#donotshowtypedkeysCurses.init_screenCurses.stdscr.keypad(true)#enablearrowkeys(forpageup/down)Curses.stdscr.nodelay=1Curses.clearCurses.setpos(0,0)Curses.addstr"Hello
状态:我正在构建一个应用程序,其中需要一个可供用户选择颜色的字段,该字段将包含RGB颜色代码字符串。我已经测试了一个看起来很漂亮但效果不佳的。它是“挑剔的颜色”,并托管在此存储库中:https://github.com/Astorsoft/picky-color.在这里我打开一个关于它的一些问题的问题。问题:请建议我在Rails3应用程序中使用一些颜色选择器。 最佳答案 也许页面上的列表jQueryUIDevelopment:ColorPicker为您提供开箱即用的产品。原因是jQuery现在包含在Rails3应用程序中,因此使用基
导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶
我需要尝试一些AES片段。我有一些密文c和一个keyk。密文已使用AES-CBC加密,并在前面加上IV。不存在填充,纯文本的长度是16的倍数。所以我这样做:aes=OpenSSL::Cipher::Cipher.new("AES-128-CCB")aes.decryptaes.key=kaes.iv=c[0..15]aes.update(c[16..63])+aes.final它工作得很好。现在我需要手动执行CBC模式,所以我需要单个block的“普通”AES解密。我正在尝试这个:aes=OpenSSL::Cipher::Cipher.new("AES-128-ECB")aes.dec
Heroku支持人员告诉我,为了在我的Web应用程序中使用自定义字体(未安装在系统中,您可以在bash控制台中使用fc-list查看已安装的字体)我必须部署一个包含所有字体的.fonts文件夹里面的字体。问题是我不知道该怎么做。我的意思是,我不知道文件名是否必须遵循heroku的任何特殊模式,或者我必须在我的代码中做一些事情来考虑这种字体,或者如果我将它包含在文件夹中它是自动的......事实是,我尝试以不同的方式更改字体的文件名,但根本没有使用该字体。为了提供更多详细信息,我们使用字体的过程是将PDF转换为图像,更具体地说,使用rghostgem。并且最终图像根本不使用自定义字体。在
在我让另一个人重做我的前端UI之前,我的Rails应用程序运行平稳。我已经尝试解决此错误3天了。这是错误:Nosuchfileordirectory-identifyExtractedsource(aroundline#59):575859606162@post=Post.find(params[:id])authorize@postif@post.update_attributes(post_params)flash[:notice]="Postwasupdated."redirect_to[@topic,@post]else{"utf8"=>"✓","_method"=>"patc
如果我们有一个数组array=[1,1,0,0,2,3,0,0,0,3,3,3]我们如何识别给定数字的运行(具有相同值的连续数字的数量)?例如:run_pattern_for(array,0)->2run_pattern_for(array,3)->1run_pattern_for(array,1)->1run_pattern_for(array,2)->0没有2的运行,因为没有连续出现2。3有一个运行,因为只有一个幻影以树为连续数字。 最佳答案 尝试:classArraydefcount_runs(element)chunk{|n