首先请出我们的主角


我们今天要识别的就是这张图片,然后首先我们来看看最后的识别效果

虽然识别出来之后画的标记不是很好,但是只要位置信息出来了,画标记其实是次要的了。

预备知识

这里先介绍一下用到的OpenCV中的名词(有函数有类)

Mat:类名,用于储存图像

namedWindow:使imshow函数展示的图片窗口大小可调

imshow:展示图片,并自定义图片窗口名

RotatedRect:旋转矩形,类名

Point2f:一个点,点的两个坐标为float型变量

points:返回旋转矩形的四个顶点

line:连线函数,参数的意义为:绘制的图片,点1,点2,线的颜色,线的宽度

cvtColor:将图片转化为灰度图,三个参数的含义为:输入图片,输出图片,转换的细节(我也刚学,建议csdn)

threshold:将图片转化为灰度图:五个参数的含义为:输入图片,输出图片,亮度下界,亮度上界(上下界之中的像素会被置为白色,其余为黑色),转化细节(不了解,同上^ 3^)

split:人如其名,将一张图片的RGB分裂开来,以BGR的顺序存在Mat数组中(便于后面的寻找颜色位置)

subtract:做减法,不过对象为两张图片,三个参数为:被减数,减数,差
不过这里需要注意的是,RoboMaster里面只有两种装甲板,红色和蓝色,红色我们就红减蓝,蓝色我们就蓝减红

getStructuringElement:的意义是创建一个用于膨胀操作的图形,两个参数的含义是:图形类型(有矩形,椭圆啥的),大小

dilate:膨胀操作,三个参数的含义为:输入图像,输出图像,膨胀用的图形

Point:表示一个点

findContours:根据二值图片,寻找二值位置的轮廓,四个参数的含义为:输入图片,储存轮廓容器,后面两个是找轮廓的选项(我也不是很了解)

auto:这个不用多说哈

minAreaRect:找到能够装下这个轮廓的最小矩形

waitKey:设置展示图片多久自动关闭窗口,单位为毫秒,若为0,则为手动关闭

然后我们一步步介绍识别步骤

(所有实现基于VS2017+OpenCV4.1.1

首先我们需要读入图片,用库函数imread读入,我们的图片文件需要与main文件在同一位置,不然我这样读取会报错

然后对其进行预处理(传入pretreat函数中),预处理的目的是得到一张经过膨胀操作后的二值图,再用后续的操作得到轮廓并画出

现在我们先介绍pretreat函数:

首先我们将传入的图片转换为一个灰度图
cvtColor(raw, grey, COLOR_BGR2GRAY);

然后转化为二值图
threshold(grey, bigrey, 150, 255, THRESH_BINARY);

再将原图RGB分离
split(raw, channel);

将B通道减去R通道
subtract(channel[0], channel[2], sub_br);

将相减之后的图片二值化
threshold(sub_br, sub_br, 110, 255, THRESH_BINARY);

创建一个用于膨胀的图形
Mat element1 = getStructuringElement(MORPH_RECT, Size(3, 3));

进行膨胀操作
dilate(sub_br, sub_br, element1);

ret = sub_br & bigrey;这一句,我们用原图 灰度二值 之后的图片与(&)上原图 通道相减二值膨胀 之后的图片,提取出较为可信的候选区域后,再进行膨胀

创建另一个用于膨胀的图片
Mat element2 = getStructuringElement(MORPH_RECT, Size(2, 2));

对我们与操作之后的结果进行膨胀操作
dilate(ret, ret, element2);

然后将ret作为结果传出

可能会很疑惑,这些参数都是怎么来的
没错都是一个个试出来的,换了图片就不一定管用了



然后介绍一下fixarmor函数(后续的展示基于原图)

其实这张图经过预处理之后还会剩余很多的不需要的白色色块,这个时候就需要我们用匹配进行取舍,只有能够配对的我们才将其保留下来
还有就是,这里的匹配操作的时间复杂度是 O(n2),我说实话我不知道有没有更好的匹配方法

contour:我们储存轮廓的容器,但是我不知道为什么需要这么创建(指模板参数)考ccf差点坑死我(指创建方式)

rect:存我们匹配后的所有矩形

ret:最后配对成功时,会以pair的形式存在ret中

findContours(img, contour, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);找轮廓

然后将轮廓弄成矩形后,存在rect

(这里用找到的temp画的图)

然后双重for,匹配灯条(匹配完之后就是我们最后的结果,所以不展示了)
我这里用了角度,面积,长宽比进行筛选
(除了长宽比需要用取出的长除取出的宽之外,其余两个都是成员变量)

后面就是匹配,没错参数也是我一个个试出来的

最后是源码:(这个没有分文件编写

#include<opencv2/opencv.hpp>
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
using namespace cv;void show(Mat img, string name)
{namedWindow(name, 0);imshow(name, img);return;
}void drawrect(Mat &img, RotatedRect ob)
{Point2f v[4];ob.points(v);for (int i = 0; i < 4; i++)line(img, v[i], v[(i + 1) % 4], Scalar(0, 255, 0), 1);return;
}void drawtarget(Mat &img, RotatedRect ob1, RotatedRect ob2)
{Point2f v1[4], v2[4];ob1.points(v1);ob2.points(v2);line(img, v1[0], v1[1], Scalar(0, 255, 0), 1);line(img, v1[0], v2[3], Scalar(0, 255, 0), 1);line(img, v2[2], v1[1], Scalar(0, 255, 0), 1);line(img, v2[2], v2[3], Scalar(0, 255, 0), 1);return;
}Mat pretreat(Mat raw)
{Mat grey;cvtColor(raw, grey, COLOR_BGR2GRAY);Mat bigrey;threshold(grey, bigrey, 150, 255, THRESH_BINARY);Mat channel[3];split(raw, channel);Mat sub_br;subtract(channel[0], channel[2], sub_br);threshold(sub_br, sub_br, 110, 255, THRESH_BINARY);Mat element1 = getStructuringElement(MORPH_RECT, Size(3, 3));dilate(sub_br, sub_br, element1);Mat ret;ret = sub_br & bigrey;Mat element2 = getStructuringElement(MORPH_RECT, Size(2, 2));dilate(ret, ret, element2);return ret;
}void fixarmor(Mat &raw,Mat img)
{vector<vector<Point>> contour;vector<RotatedRect> rect,finall;vector<pair<RotatedRect, RotatedRect>> ret;findContours(img, contour, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);for (auto x : contour){RotatedRect temp = minAreaRect(x);rect.push_back(temp);}for (auto x : rect){for (auto y : rect){double xangle, yangle, xarea, yarea, xrate, yrate;xarea = x.size.area();xangle = x.angle;yarea = y.size.area();yangle = y.angle;xrate = x.size.height / x.size.width;yrate = y.size.height / y.size.width;if (xarea == yarea) continue;if (xangle > 10 || yangle > 10) continue;if (xarea < 15 || yarea < 15) continue;if (fabs(xarea - yarea) < 20 && fabs(xangle - yangle) < 2&& fabs(xrate - yrate) < 0.1&&fabs(x.size.height - y.size.height) < 5&& fabs(x.size.width - y.size.width) < 5)ret.push_back({ x,y });}}//cout << ret.size() << endl;for (auto x : ret) { drawrect(raw, x.first); drawrect(raw, x.second);}for (auto x : ret) drawtarget(raw, x.first, x.second);return;
}int main()
{Mat hero = imread("hero.jpg");Mat temp = pretreat(hero);fixarmor(hero,temp);show(hero, "hero");waitKey(0);//system("pause");return 0;
}

然后按道理是可以将蓝减红改成红减蓝来识别红色灯条的我没试过,如果识别不了,可以评论私信找我击剑

截中间图好麻烦
不要问我为什么用绿色画图,我做题看不到绿色,所以我要多看看绿色

对一张静态图片的识别相关推荐

  1. Python 实现 GIF 动态图片分解 , 多帧动态图分解成多张静态图片

    文章目录 需求 实现 参考 需求 有时候你看到一张动态图片,其中的一个画面你觉得很不错,想从中提取出来.例如以下这张由多个漂亮小姐姐组成的 GIF 动态图: 实现 GIF 动态图片是由多张静态图片组合 ...

  2. c语言静态图片做成动态效果,怎样把图片做成动态图 两张静态图片加过渡效果制作成gif动图...

    近日有朋友问小编说:有两张带文字的图片文件,想要制作成gif格式的动图,并且这两张图片要加上自然的过渡效果,这样怎么制作呢?其实咱们狸窝家园也是有挺多图片制作成gif动图的方法的,只是要添加自然的过渡 ...

  3. php合并多张gif图,多张静态图片合成一张动态图-静图合成动图制作

    现如今制作gif图片也不是什么难事了,巧用动态图合成软件,即能轻松将多张静态图片合成一张动态图.动态图片是由多张不同的静态图片组合而成的gif格式图片,它会按照一定的顺序和时间进行逐帧播放.做好的动态 ...

  4. android 静态图片自动切换,Android静态图片人脸识别的完整demo(附完整源码)

    Android静态图片人脸识别的完整demo(附完整源码) 来源:互联网 作者:佚名 时间:2015-03-24 20:07 本文介绍了android静态识别人脸并进行标记人眼位置及人脸框的完整dem ...

  5. PhotoShop cc合并多张静态图片为gif动画

     合并静态图片为动态图步骤: 1.新建空白区域 2.选择文件-->置入嵌入的智能对象,选择你要合并的图片第一张 3.把图片填充满空白区域,确认 4.创建时间轴 5.点击转为帧动画 6,删除背 ...

  6. 在html中加入一个动态图,图片上加gif图片 图片某个角落贴个gif动态图,如何在静态图片上面加一张GIF动态图...

    喜欢上网的小伙伴就会知道网上流传灰常广泛一种搞笑gif动态图片,这类图片大部分是视频转gif的,就是截取视频经典搞笑画面制作而成,还加了些搞笑文字.使用网络聊天工具尤其是QQ就最常见了,那些搞笑的表情 ...

  7. jpg怎么合成一份_如何将多张JPG图片合并成一个GIF?

    原标题:如何将多张JPG图片合并成一个GIF? 今天是广东入秋成功的某一天,虽然天气变冷了,但外面的紫外线还是毒辣得很,所以大家还是在室内跟小编一起研究教程方案吧! 今天要给大家介绍的是将多张静图合并 ...

  8. I9003静态图片的位置及蓝牙发送

    I9003自带的几张静态图片很漂亮,想传给别人,可惜找不到在哪. 凭着经验用91助手在手机的各种目录中寻找,终于找到了.system/app/TwWallpaperChooser.apk,就是这个程序 ...

  9. 在静态图片上加跳转链接

    开发中常会遇到一张静态图片,需要点击图片不同位置跳转链接如下图 因为手机屏幕的大小不同,设置图片宽度为100%,根据浏览器渲染图片机制,高度会根据宽度等比例缩放 <img src="h ...

  10. python相似图片识别_Python+Opencv识别两张相似图片

    Python+Opencv识别两张相似图片 在网上看到python做图像识别的相关文章后,真心感觉python的功能实在太强大,因此将这些文章总结一下,建立一下自己的知识体系. 当然了,图像识别这个话 ...

最新文章

  1. NotePad++列编辑
  2. swift笔记三 使用xcode
  3. Laravel 5.0 的新特性
  4. 计算机课程职业素质考核,中职计算机课程中多元化考核的探索与实践
  5. yarn临时目录 没有jar包_复习之yarn
  6. C# Regex 深入正则表达式
  7. js - 预加载+监听图片资源加载制作进度条
  8. linux oom-killer
  9. jdbc、PreparedStatement预编译原理
  10. 禁用EnableViewState和启用EnableViewStat时请注意
  11. linux安装智能输入法,Ubuntu 8.04中安装智能拼音输入法
  12. Thinkphp5 php会员实现单点登录
  13. java 约分_约分的方法
  14. 新增数学与人工智能学部,考数据结构!齐鲁工业大学(山东省科学院)计算机考研...
  15. 转:查尔斯·汉迪:你是谁,比你做什么更重要
  16. 计算机硬件相关研究内容,计算机硬件论文提纲格式范本 计算机硬件论文提纲怎样写...
  17. 财神来了 | 那些年伤害过你的分叉币
  18. php网页全屏背景图代码,HTML5 body设置全屏背景图片的示例代码
  19. 自定义 ViewGroup,实现多功能流式布局与网格布局
  20. Visual Stdio C++ 编译器 编译 (GSL) GNU Scientific Library 的方法介绍(5)

热门文章

  1. 模拟摄像机和网络摄像机的简要对比
  2. 易到实际控制人温晓东成老赖:与贾跃亭曾是盟友 如今反目
  3. VMware16安装Ubuntu22.04(并解决vmtools问题)
  4. 【ROS】ubuntu20.04+ROS安装上遇到的坑(主要是time out)
  5. MybatisPlus IPage<V>转IPage<B> 封装工具类
  6. 【Android初学者】UI组件 介绍
  7. 任正非带领华为三分天下的7大杀招
  8. 堆栈c语言 矩形填色,堆栈涂色官方版下载|堆栈涂色安卓版v0.1下载 - 一游网手机游戏...
  9. App Store提交上线、市场推广专题
  10. 2018APP推广计划方案(完整版)