我的战队
【分享帖】无论你走到天涯海角,我都能找到你!
萝卜君已经出现了那么多次了,你们是不是都忘了小R,告诉你们,tan90°;P,小R最近在忙大事哦,
啦啦啦啦 他就是机器视觉。
总而言之:机器视觉大法好,(嗯 说好的鸡腿呢!!!)
在 RoboMaster 比赛中,当一台机器人移动时,另一台机器人在无人操作的情况下,好像有着一双眼睛,可以自动瞄准移动的机器人。


红方追踪移动的蓝方

实际上,都是因为机器视觉大法好啊!

在这个场景中,机器人搭载的摄像头把图像实时传输到电脑,通过电脑程序分析。即使图像内目标物体快速移动,它的位置信息也会被获取并实时追踪,很难被甩掉。

什么?你不知道机器人上有电脑?来,先仔细地看一遍:




看到摄像头和电脑了吗?

我们告诉电脑目标物体都有哪些特征,它就会完全按照我们预设的程序来运行,这种视觉处理方法可归为传统方式。

传统式的机器视觉适合入门学习。今天我们先来讲讲视觉识别中处理程序的一环:到底电脑是如何识别和处理图像的呢?想闭着眼睛操控机器人的小伙伴,注意听讲啦~

◆◆◆

《论语·卫灵公》:“工欲善其事,必先利其器。”做机器视觉也一样,我们需要高效的编程环境,以及让你事半功倍的武器——OpenCV 视觉库。OpenCV 是广泛应用的视觉识别库,它提供了开源的代码供直接调用。

OpenCV 简介

全称 Open Source Computer Vision Library,直译成中文就是“开源的计算机视觉库”。它“普度众生”,可以运行在 Linux(一种用来干活的操作系统)、Windows(一种又能干活又能玩的操作系统)和 MacOS(一种只能运行在昂贵电脑上的操作系统)等操作系统上。

OpenCV 大概就是传说中的天使了

说起喜欢 OpenCV 的原因,很多参赛队员都谈到了两点。第一,OpenCV 是免费开源的,由一个非盈利性组织支持;第二,OpenCV 非常轻量级,这意味着,大部分程序在普通的电脑上也能运行。

OpenCV 有上百个函数,根据不同功能划分到不同的功能模块里。这些功能模块一点也不多,大概就那么十几二十吧(・∀・*)……


检验学霸之图

客官请留步!耐心看一看

作为初学者
你只需要先掌握
core、imgproc、highgui 这三个基本模块
因为这三个模块提供了最基础和常用的接口

为了生动地教学~
(为了让文章不被关掉)
小R贴心地准备了
一系列超详细的教程
带领你走进视觉识别的大门~

不用谢:)

图像的矩阵形式

OpenCV 的 core 内核模块为我们提供了最核心的类和接口。其中, Mat 类型将图像以矩阵的方式存储,更适合计算机做数值运算。


小R最喜欢的图竟然是个矩阵?!

以最简单的黑白位图照片为例。我们把图片放大之后,可以看到图像实际上是由许多明暗不同的小方块(像素)组成的。


位图图像是由很多像素组成的

在8位的灰度色彩空间里,我们把这些小方块用0~255的数字代替,数值越小代表的方块越暗。


8位灰度色彩空间

按照这个方法,我们就可以把图像用数字矩阵的方式存储。

所以,电脑程序分析图像的原理,很大程度上是矩阵中的数学运算。
(赶紧掏出了线性代数的课本)

◆◆◆

通常,视觉识别分为两步。第一步是“预处理”,通过一些基础算法,去除无用信息和噪声,放大颜色间的差异;第二步,就是利用其特征信息进行“物体检测”。


常见视觉识别步骤

接下来,我们就通过两个超实用的视觉识别例子,来理解预处理和物体检测。

预处理

选取讲解的素材需要非常慎重。好的,现在我们决定用萝卜君。


萝卜君原始图片

我们先用 core 内核模块中的 imread 读图像函数把这张图片以矩阵形式载入到内存中,并起个好听的名字叫做 src 。

Mat src = imread("萝卜君.jpg");

接下来,用遍历像素点的方法,找到所有蓝色像素,把它变成白色。伪代码如下:

i 从 0 循环至 图像.宽 :
j 从 0 循环至 图像.高 :
如果 像素点( i , j ) 是 蓝色
巴啦啦能量!像素点( i , j ) 变成 白色!

(好的,谢谢伪代码君)

完成这一步操作的 C++ 代码,有三种方法:

1、传统的C风格操作符[] (指针)
for (int i = 0; i <src.rows; i++) {
Vec3b* data =src.ptr<Vec3b>(i);
for (int j = 0; j <src.cols; j++) {
if (data[j][0] > 200 && data[j][2] < 50)
data[j] = Vec3b(255, 255, 255);
}
}

2、迭代器方法
MatIterator_<Vec3b> it, end;
for (it =src.begin<Vec3b>(), end =src.end<Vec3b>(); it != end; ++it)
if ((*it)[0] > 200 && (*it)[2] < 50) {
(*it)[0] = 255;
(*it)[1] = 255;
(*it)[2] = 255;
}

3、返回引用的动态地址访问函数*
*原文:On-the-fly address calculation with reference returning
for (int i = 0; i <src.rows; ++i)
for (int j = 0; j <src.cols; ++j) {
Vec3b pixel =src.at<Vec3b>(i, j);
if (pixel[0] > 200 && pixel[2] < 50) {
src.at<Vec3b>(i, j) = Vec3b(255, 255, 255);
}
}

这三种方法中,第 1 种方法效率最高,但在使用之前,你需要先确保该图像在内存内是连续存储的。建议操作之前先调用函数 isContinuous() 来判断。

但相比之下,第 2 种方法更安全。它会帮你自动跳过内存内的不连续空间,同时也保持了很高的效率。

第 3 种方法是被设定来随机访问像素点的,你要是用它来遍历图像,那效率堪称感人。等你找到萝卜君的时候,他可能把下周的视频都做完了。

那我们就挑一种自己喜爱的方法,完成这一步操作:遍历全图,把蓝色的像素点变成白色。它有点像我们常说的“抠图”。


背景处理对比

(这么干净的背景在现实中是不可能存在的)

经过去除背景之后的图片,仍然有很多像椒盐一样的噪声点,我们管它叫做"椒盐噪声"。

OpenCV 的 imgproc 模块,内含滤波、形态学处理、几何变换等大量实用的图像处理函数,把它们像互相组合起来,足以应对各种场景需求。

例如,图像非线性滤波算法中的中值滤波 medianBlur,对于滤除图像中的“椒盐噪声”,效果优异。

cv::medianBlur(src,dst,3);


滤除椒盐噪声对比

看到了吗!
左图中的“椒盐噪声”,在右图中就消失了!
(没看到的多看几遍)

经过预处理之后的图片
干~干~净~净~
这个时候我们就可以进行物体检测啦!

现在把萝卜君换成机器人

物体检测

我们把机器人跟萝卜君一样,进行图片“预处理”,去掉背景杂色,只保留发光的灯条。


预处理后的图像

接下来,使用 findConours 函数,找出装甲片灯条的轮廓;再使用 minAreaRect 函数,将“看起来像矩形”的灯条直接拟合成 RotationRect 旋转矩形。将灯条变成规则的几何图案,更有利于之后的特征分析。

献上我们的代码君:
//在bin_img二值图中查找轮廓,并放到 contours 里
findContours(bin_img, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
//将灯条拟合成 RotationRect 旋转矩形
RotatedRect minRect = minAreaRect(Mat(contours));


测距效果

这里的 minRect 就是一个 RotationRect 旋转矩形的实例,它包含了矩形的位置和形态信息。接下来,根据灯条姿态,结合利用装甲片、灯条尺寸等先验知识,就可以换算出目标装甲模块的相对坐标啦!

在 RoboMaster 比赛中,当获取到目标的相对坐标后,分析图像,就能进一步控制云台瞄准打击目标啦,妥妥的~

本期的机器视觉入门就到这里,讲了这么多,有没有听进去呀?祝大家学习路上大吉大利,将来一起吃“反鸡”!



想了解更多
可在 PC 端点击阅读原文下载
装甲模块自动识别开源代码

◆◆◆

与传统式对比起来,还有另外一种高级的机器视觉处理。

在 2017 赛季 RoboMaster 比赛中,出现了一个动态变化的九宫格大能量机关,机器人需要先识别机关上方随机出现的一行数码管数字,再按照其顺序识别下方随机分布、随机字体的九宫格数字。因为其字体是随机的,很难手动输入所有特征,这里就需要用到机器学习:给机器人一些事先准备好的例子,让它自己学习、摸索。


视觉识别数字

这种丑丑的手写体数字就无法用传统方式来识别了,关注我们,下一期更加高级的机器学习式视觉识别教学,周日准时带你飞。

链接如下:http://mp.weixin.qq.com/s/1IhRLRV2oPopXC-sz4oS-w


2051794207.jpg


1980180434.jpg


41748672.jpg


1226058204.jpg


483508158.jpg


866989278.jpg


715035217.jpg


996198169.jpg


555031738.jpg


webwxgetmsgimg.jpg


webwxgetmsgimg (2).jpg


760945965.jpg


1980180434.jpg

请问这篇文章对你有用吗?
【分享帖】无论你走到天涯海角,我都能找到你!
所有评论
暂无更多
关于作者
0 关注Ta
0 文章
0 经验值
0 获赞