用OpenMV自动识别颜色序列

新年假期过去啦~

主控:OpenMV3 M7摄像头(STM32F765)

IDE:OPENMV官方IDE

我将Capstone期间做的代码上传到Gitee啦,后续还会陆续上传代码上去的,地址:Capstone,如果对你有帮助的话不妨点个支持一下~

OpenMV需要识别颜色顺序的位置是第一个区域,区域中的物料摆放如下图所示

对于OpenMV识别颜色,很大一部分人都是采用了使用阈值调节,通过拍回来的照片修改阈值得到想要的区域,这种情况一般都会存在调试时间长,受光照影响大的限制。

通过分析本项目的颜色识别部分,小车到达粗加工区后开始颜色识别,识别到序列之后在开始抓取,车子在识别颜色时的位置是大致不变的,所以本文将阈值->颜色识别的流程转化为区域->颜色的识别,可以减少调试时间,但解决不了受光照影响的问题。

OpenMV使用的是LAB色域,如下图所示

根据任务要求,物料颜色分别有红绿蓝三色,则对上图进行观察对比,可以发现红绿蓝三色均在球形的外端,有非明显的区别,比如红色的a值为正数蓝色的b值为负数绿色的a值为负数。因此可以根据这些特征筛选出所需颜色。

在实际运行过程中,我们将OpenMV的画面分成上下两部分,然后在每次运行到粗加工区位置时都运行一遍识别程序,避免因颜色识别不全卡在粗加工区。

在此处放出获取区域颜色的代码

function:GetColor

def GetColor(Rev_Num):
global Left_x
global Middle_x
global Right_x
global Left_y
global Middle_y
global Right_y
global LeftMean_Shang
global MiddleMean_Shang
global RightMean_Shang
global LeftMean_Xia
global MiddleMean_Xia
global RightMean_Xia
if (Rev_Num == 1):
#获取左中右三个位置的X坐标和Y坐标
Left_x = LeftROI_Shang[0] + (LeftROI_Shang[2] / 2)
Middle_x = MiddleROI_Shang[0] + (MiddleROI_Shang[2] / 2)
Right_x = RightROI_Shang[0] + (RightROI_Shang[2] / 2)
Left_y = LeftROI_Shang[1] + (LeftROI_Shang[3] / 2)
Middle_y = MiddleROI_Shang[1] + (MiddleROI_Shang[3] / 2)
Right_y = RightROI_Shang[1] + (RightROI_Shang[3] / 2)
for i in range(100):
img = sensor.snapshot()
img.draw_rectangle(LeftROI_Shang)
img.draw_rectangle(MiddleROI_Shang)
img.draw_rectangle(RightROI_Shang)
img.draw_cross(int(Left_x), int(Left_y))
img.draw_cross(int(Middle_x), int(Middle_y))
img.draw_cross(int(Right_x), int(Right_y))
Left_Stat = img.get_statistics(roi = LeftROI_Shang)
Middle_Stat = img.get_statistics(roi = MiddleROI_Shang)
Right_Stat = img.get_statistics(roi = RightROI_Shang)
#获取上层左侧ROI的LAB均值
LeftMean_Shang[0] = LeftMean_Shang[0] + (Left_Stat.l_mean() / 100)
LeftMean_Shang[1] = LeftMean_Shang[1] + (Left_Stat.a_mean() / 100)
LeftMean_Shang[2] = LeftMean_Shang[2] + (Left_Stat.b_mean() / 100)
#获取上层中间ROI的LAB均值
MiddleMean_Shang[0] = MiddleMean_Shang[0] + (Middle_Stat.l_mean() / 100)
MiddleMean_Shang[1] = MiddleMean_Shang[1] + (Middle_Stat.a_mean() / 100)
MiddleMean_Shang[2] = MiddleMean_Shang[2] + (Middle_Stat.b_mean() / 100)
#获取上层右侧ROI的LAB均值
RightMean_Shang[0] = RightMean_Shang[0] + (Right_Stat.l_mean() / 100)
RightMean_Shang[1] = RightMean_Shang[1] + (Right_Stat.a_mean() / 100)
RightMean_Shang[2] = RightMean_Shang[2] + (Right_Stat.b_mean() / 100)
elif (Rev_Num == 2):
#获取左中右三个位置的X坐标和Y坐标
Left_x = LeftROI_Xia[0] + (LeftROI_Xia[2] / 2)
Middle_x = MiddleROI_Xia[0] + (MiddleROI_Xia[2] / 2)
Right_x = RightROI_Xia[0] + (RightROI_Xia[2] / 2)
Left_y = LeftROI_Xia[1] + (LeftROI_Xia[3] / 2)
Middle_y = MiddleROI_Xia[1] + (MiddleROI_Xia[3] / 2)
Right_y = RightROI_Xia[1] + (RightROI_Xia[3] / 2)
for i in range(100):
img = sensor.snapshot()
img.draw_rectangle(LeftROI_Xia)
img.draw_rectangle(MiddleROI_Xia)
img.draw_rectangle(RightROI_Xia)
img.draw_cross(int(Left_x), int(Left_y))
img.draw_cross(int(Middle_x), int(Middle_y))
img.draw_cross(int(Right_x), int(Right_y))
Left_Stat = img.get_statistics(roi = LeftROI_Xia)
Middle_Stat = img.get_statistics(roi = MiddleROI_Xia)
Right_Stat = img.get_statistics(roi = RightROI_Xia)
#获取下层左侧ROI的LAB均值
LeftMean_Xia[0] = LeftMean_Xia[0] + (Left_Stat.l_mean() / 100)
LeftMean_Xia[1] = LeftMean_Xia[1] + (Left_Stat.a_mean() / 100)
LeftMean_Xia[2] = LeftMean_Xia[2] + (Left_Stat.b_mean() / 100)
#获取下层中间ROI的LAB均值
MiddleMean_Xia[0] = MiddleMean_Xia[0] + (Middle_Stat.l_mean() / 100)
MiddleMean_Xia[1] = MiddleMean_Xia[1] + (Middle_Stat.a_mean() / 100)
MiddleMean_Xia[2] = MiddleMean_Xia[2] + (Middle_Stat.b_mean() / 100)
#获取下层右侧ROI的LAB均值
RightMean_Xia[0] = RightMean_Xia[0] + (Right_Stat.l_mean() / 100)
RightMean_Xia[1] = RightMean_Xia[1] + (Right_Stat.a_mean() / 100)
RightMean_Xia[2] = RightMean_Xia[2] + (Right_Stat.b_mean() / 100)

简单介绍一下函数,函数内容挺简单的,将画面中三个区域中的LAB阈值提出来做均分再相加,就得到了三个区域中L、A、B三个通道的颜色均值,后面再做对比就行

还有调试用的函数,这个函数是用来调试找到三个区域的

function:Get_ROI

def Get_ROI(Rev_Num):
global Left_x
global Middle_x
global Right_x
global Left_y
global Middle_y
global Right_y
if (Rev_Num == 1):
#裁剪窗口
sensor.set_windowing(ROI_Shang)
#获取左中右三个位置的X坐标和Y坐标
Left_x = LeftROI_Shang[0] + (LeftROI_Shang[2] / 2)
Middle_x = MiddleROI_Shang[0] + (MiddleROI_Shang[2] / 2)
Right_x = RightROI_Shang[0] + (RightROI_Shang[2] / 2)
Left_y = LeftROI_Shang[1] + (LeftROI_Shang[3] / 2)
Middle_y = MiddleROI_Shang[1] + (MiddleROI_Shang[3] / 2)
Right_y = RightROI_Shang[1] + (RightROI_Shang[3] / 2)
img = sensor.snapshot()
img.draw_rectangle(LeftROI_Shang)
img.draw_rectangle(MiddleROI_Shang)
img.draw_rectangle(RightROI_Shang)
img.draw_cross(int(Left_x), int(Left_y))
img.draw_cross(int(Middle_x), int(Middle_y))
img.draw_cross(int(Right_x), int(Right_y))
elif (Rev_Num == 2):
#裁剪窗口
#sensor.set_windowing(ROI_Xia)
#获取左中右三个位置的X坐标和Y坐标
Left_x = LeftROI_Xia[0] + (LeftROI_Xia[2] / 2)
Middle_x = MiddleROI_Xia[0] + (MiddleROI_Xia[2] / 2)
Right_x = RightROI_Xia[0] + (RightROI_Xia[2] / 2)
Left_y = LeftROI_Xia[1] + (LeftROI_Xia[3] / 2)
Middle_y = MiddleROI_Xia[1] + (MiddleROI_Xia[3] / 2)
Right_y = RightROI_Xia[1] + (RightROI_Xia[3] / 2)
img = sensor.snapshot()
img.draw_rectangle(LeftROI_Xia)
img.draw_rectangle(MiddleROI_Xia)
img.draw_rectangle(RightROI_Xia)
img.draw_cross(int(Left_x), int(Left_y))
img.draw_cross(int(Middle_x), int(Middle_y))
img.draw_cross(int(Right_x), int(Right_y))

完整的代码发在了Gitee上

程序的运行结果如下图,可以成功的识别得到颜色的序列

手上没有openmv,测试图就这一张

用OpenMV自动识别颜色序列的更多相关文章

  1. cojs 疯狂的魔法树 疯狂的颜色序列 题解报告

    疯狂的魔法树 一个各种操作大杂烩的鬼畜数据结构题目 首先我们注意到树的形态是半随机的 我们可以树分块,对树分成若干个块 对于每个块我们维护一个add标记表示增量 维护一个vis标记表示覆盖量 注意标记 ...

  2. 用Arduino显示颜色序列(u8g2,OLED)

    目录 用Arduino显示颜色序列(u8g2,OLED) 用Arduino显示颜色序列(u8g2,OLED) 提前祝大家新年快乐! 主控:Arduino Mega 2560 硬件:126×64 OLE ...

  3. [四校联考P3] 区间颜色众数 (主席树)

    主席树 Description 给定一个长度为 N 颜色序列A,有M个询问:每次询问一个区间里是否有一种颜色的数量超过了区间的一半,并指出是哪种颜色. Input 输入文件第一行有两个整数:N和C 输 ...

  4. Uva 1625,颜色的长度

    类似于LCS的动态规划,指标函数的分解. 题目链接:https://uva.onlinejudge.org/external/16/1625.pdf 题目大意:两个颜色序列,将他们合并,合并的时候,每 ...

  5. shell之echo与printf和颜色

    在用户的bashrc中添加一行export来修改提示符.

  6. bzoj5011: [Jx2017]颜色

    Description 可怜有一个长度为n的正整数序列Ai,其中相同的正整数代表着相同的颜色. 现在可怜觉得这个序列太长了,于是她决定选择一些颜色把这些颜色的所有位置都删去. 删除颜色i可以定义为把所 ...

  7. UVa 1625 颜色的长度

    https://vjudge.net/problem/UVA-1625 题意: 输入两个长度分别为n和m的颜色序列,要求按顺序合并成同一个序列,即每次可以把一个序列开头的颜色放到新序列的尾部.对于每个 ...

  8. opencv产生随机的颜色

    //将HSV颜色空间值转换成RGB值,参考这里cv::Scalar HSV2RGB(const float h, const float s, const float v) { ); - h_i; - ...

  9. [JXOI2017]颜色 线段树求点对贡献

    [JXOI2017]颜色 题目链接 https://www.luogu.org/problemnew/show/P4065 题目描述 可怜有一个长度为 n 的正整数序列 Ai,其中相同的正整数代表着相 ...

随机推荐

  1. Android开发 之 理解Handler、Looper、MessageQueue、Thread关系

    本文转自博客:http://blog.csdn.net/he90227/article/details/43567073 一. 图解与概述 首先Android中 的每一个线程都会对应一个Message ...

  2. Python pip下载慢的解决方法

    国外的源下载速度实在是太慢了 可以使用国内的一些镜像网站安装 使用cmd命令 格式:pip install -i 网站 库 例如: 国内的一些镜像网站 清华大学:https://pypi.tuna.t ...

  3. vue行内动态添加样式或者动态添加类名

    还是记录一下吧(๑•ᴗ•๑) <li :style="{backgroundImage:`url(${item.pic})`}" @click="chooseVip ...

  4. redis笔记补充

    redis补充 这篇文章是redis入门笔记的补充. 1.info命令 用来显示服务的信息. info命令可以跟下面的选项: server: 关于 Redis 服务器的一些信息 clients: 客户 ...

  5. 2.Docker容器学习之新生入门必备基础知识

    0x02 Docker 核心概念 描述:Docker的三大核心概念镜像/容器和仓库, 通过三大对象核心概念所构建的高效工作流程; 1.镜像 [image] 描述:images 类似于虚拟机镜像,借鉴了 ...

  6. B. Lord of the Values 思维数学建构 附加 英文翻译

    原题链接 Problem - 1523B - Codeforces 题目及部分翻译 While trading on(贸易,利用) his favorite exchange trader Willi ...

  7. ReLabel:自动将ImageNet转化成多标签数据集,更准确地有监督训练 | 2021新文

    人工标注数据集中普遍存在噪声,ReLabel能够自动且低成本地将原本的单标签数据集转化为多标签数据集,并且提出配合random crop使用的高效LabelPooling方法,能够更准确地指导分类网络 ...

  8. 【笔记】PyTorch快速入门:基础部分合集

    PyTorch快速入门 Tensors Tensors贯穿PyTorch始终 和多维数组很相似,一个特点是可以硬件加速 Tensors的初始化 有很多方式 直接给值 data = [[1,2],[3, ...

  9. 利用VTK和PyQt5对医学体数据进行渲染并展示

    简介 在一些医学相关的简单的项目(也许是学生的作业?毕业设计?)中,有时候可能需要集成一些可视化的功能,本文简单介绍一下,如何利用PyQt5和VTK来渲染体数据(三维数据),并集成进PyQt的UI框架 ...

  10. this-3

    this是什么?JavaScript中,this关键词指的是他所属的对象:它拥有不同的值,具体取决于它的使用位置. 1.在单独情况下,this指向全局对象window:2.在函数中,this指向全局对 ...