自学图像识别

本文介绍了OpenCV中图像识别的基本步骤,包括灰度转换、模糊处理(均值滤波和高斯滤波)、二极化、腐蚀/膨胀(如椭圆和矩形结构元素)、边缘检测(Canny算子)以及轮廓检测和物体框定。这些技术是图像处理的基础,但复杂的识别需求还需结合其他函数和方法。
摘要由CSDN通过智能技术生成

图像识别

在一般的图像识别中,我们要将图片按照 模糊处理->灰度->二极化->腐蚀/膨胀->边缘检测->框住物体 来识别物体

一.灰度

cvtColor() 函数,这是一个颜色空间转换,在图像识别中,有很大的作用,可以将通道数变少,后期易于图像处理

以下是常用的操作

cvtColor(srcImage ,dstImage ,COLOR_GRAY2BGR); // 转换原始图为灰度图
cvtColor(srcImage ,dstImage ,COLOR_BGR2HSV); // 转换原始图为hsv图

原图
请添加图片描述
转化为灰度后
请添加图片描述
转化为HSV后
请添加图片描述

二.模糊处理

主要分为均值滤波,高斯滤波。

均值滤波:

blur(Mat src,Mat dst,Size(x,y),Point(-1,-1))

高斯滤波:

GaussianBlur(Mat src,Mat dst,Size(x,y),0,0,Point(-1,-1)) 

其中,x,y一般都是奇数,为了让结构元素有一个中心点,其中Point(-1,-1)表示的就是在中心点。

接下来解释一下它们的原理

均值滤波,顾名思义,是用像素点周围的邻域像素(Size)的平均值来代替point像素的值,缺点是遇到临近点像素差距大,可能会丢失重要信息,在简单识别中容易使用。

高斯滤波,是类似于正态分布函数,中心点按权值分配,可以规避均值滤波的缺点,使图像更平滑,适合干扰项较多的识别。

三.二极化

核心函数,threshold(InputArray src ,OutputArray dst, double thresh , double maxva l , int type)

补充
0代表黑色,255代表白色,中间值则为深浅不一的灰色

这是一种固定阈值的操作,常用的type是THRESH_BINARY,本质就是,在灰度处理后的图像,若低于阈值都为0,高于阈值都为1

以下是其他type下的操作方式

在这里插入图片描述

在二极化后,图像会变得有理可循,需要识别的特征物也会如约而至,如果说二极化前,是乱花渐欲迷人眼,那么,二极化后,就是柳暗花明又一村。

四.腐蚀/膨胀

一、腐蚀

1.概念

腐蚀是一种消除边界点,使边界向内部收缩的过程。可以用来消除小且无意义的目标物。如果两目标物间有细小的连通,可以选取足够大的结构元素,将细小连通腐蚀掉。

​ 简单点说就是,就是将白色区域缩小

2.算法的具体步骤

1.搭建好size大小的结构元素

2.从上到下,从左到右找到第一个像素值为1的点。

3.将结构元素的原点移动到该点

4.判断该结构元素覆盖范围内的图像的像素值是否全部为1,如果是,则腐蚀后图像相同位置上的像素值为1,如果至少有一个像素的值为0,则腐蚀后图像的相同位置上的像素值为0

5.对原图中其余像素值为1的点重复进行步骤3和步骤4

原图
在这里插入图片描述

第一次变化后
在这里插入图片描述
以此类推…

原图(左)腐蚀后(右)

3.代码

Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(2, 2));
erode(src,dst, kernel);

其中,MORPH_ELLIPSE 表示 椭圆(包括圆形)

于此类似的还有 MORPH_RECT 矩形(包括线形) MORPH_CROSS 十字形(一定要设置好锚点)

Size(2,2)即是2x2的预先设定好的形状

二、膨胀

1.概念

膨胀是将目标区域接触的背景点合并到该目标物中,使目标边界向外扩张的处理。膨胀可以用来填补目标区域存在的某些空洞,也可以用来消除包含在目标区域中的小颗粒噪声。膨胀处理是腐蚀处理的对偶。

简单来说就是,填满空隙,使物体形象更丰满,更容易理解就是让白色区域扩大。

2.原理

和腐蚀差不多,就是判断该结构元素覆盖范围内的图像的像素值是否全部为0,如果是,则腐蚀后图像相同位置上的像素值为0,如果至少有一个像素的值为1,则腐蚀后图像的相同位置上的像素值为1.

在这里插入图片描述
​ 原图 (左) 膨胀后(右)

Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(2, 2));
dilate(src,dst, kernel);

其余亦和腐蚀相似

由此,我们可以引申出开闭运算以及顶帽黑帽等,他们本质上是腐蚀和膨胀的组合。

五.边缘检测
这里介绍最好的一种:Canny算子

代码

Canny(srcImage, dsIImage , 3 (阈值1), 9(阈值2), 3 (孔径大小,默认为3))

两个阈值中较小的值用于边缘连接,而较大的值用来控制强边缘的初始段,简单来说就是,超过大阈值的为边缘,在大阈值和小阈值之间的若与超过大阈值部分连接,也看成边缘。

为什么在众多算子中,我只介绍Canny呢?
因为Canny使用了变分法,一个最优的边缘检测算法,这是很多人推崇的算子。

六.框住物体

1.寻找轮廓

vector<vector<Point>> contours;
 findContours(InputOutputArray image , OutputArrayOfArrays contours, OutputArray hierarchy, int mode , int method , Point offset=Point () );

第一个参数 Mat类的对象即可,且需为8位单通道图像

第二个参数 检测到的轮廓、函数调用后的运算结果存在这里

第三个参数 hierarchy,作为数组,来存储轮廓之间的关系(里外关系)

第四个参数 轮廓检索模式,比如RETR_EXTERNAL 表示只检测外层轮廓

第五个参数 轮廓的近似办法 一般取CHAIN APPROX SlMPLE,只保留方向终点坐标

第六个参数 每个轮廓点的可选偏移量

vector可以看成一个容器,与数组类似,区别在于vector可以自己扩展空间。

其中contours可以看出一个二位数组,用来存储相同点集的集合,实际上每一个连续的轮廓,是由一个个独立的点拼成。

like:
contours[0][];
contours[1][];

不同的第一个下标储存不同形状。

2.绘制轮廓

在储存好点集后,需要去确定要检测轮廓的中心,即用规则的图形来框住不规则轮廓。

函数名作用
minAreaRect寻找最小包围矩形
boundingRect返回外部矩形边界
minEnclosingCircle寻找最小包围圆形

代码

drawContours ( InputOutputArrayimage , InputArrayOfArrays contours, int contourldx, const Scalar& color,
 int thickness=l , int lineType=8 , InputArray hierarchy=noArray () , int maxLeve l =INT MAX , Point offset=Point () )

这一代码的效果是会有设定好颜色的线,将找到的轮廓,描绘出来。

当然你也可以根据自己想要的结果用合适的轮廓框住物体,比如最小外接矩形、最小外接圆、多边形(凸点)…

总结
上述介绍的内容,只是opencv中的冰山一角,路漫漫其修远兮,笔者尽力省去了书上复杂的原理,但是带来了省略了一些重

要信息的结果,以及更多精密识别的操作,以上讲述方法,并不能解决类似于识别颜色,识别复杂背景下的物体,这些需要

其他函数来实现。本人只是让识别更容易上手,有一个基础的认识。

参考资料

OpenCV3编程入门_毛星云编著_电子工业出版

  • 30
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值