原文标题:16 OpenCV Functions to Start your Computer Vision journey (with Python code)
原文链接:https://www.analyticsvidhya.com/blog/2019/03/opencv-functions-computer-vision-python/
作者:SAURABH PAL
简介
计算机视觉是目前工业界中最热门的领域之一。 由于科研的快速进步,它正在蓬勃发展。 但对于新手来说,这可能是一个令人生畏的领域。数据科学家在转入计算机视觉领域时会面临一些共同的挑战,包括:
1.我们如何清洗图像数据集?图像有不同的形状和大小。
2.一直存在的数据获取的问题。我们应该在构建计算机视觉模型之前收集更多图像吗?
3.构建计算机视觉模型是否必须用深度学习?我们可以不使用机器学习技术吗?
4.我们可以在自己的机器上构建计算机视觉模型吗?不是每个人都有GPU和TPU!
我确实遇到了上述挑战中的大部分,我相信大多数人也一定遇到过。这些是作为计算机视觉初学者提出的正确问题——好消息!你找对了地方。
在本文中,我们将通过使用OpenCV库回答大部分问题。它像计算机视觉任务的灯塔一样出色,很容易地成为了最受欢迎的CV库。
然而对于使用OpenCV有一个忠告——新手起步可能有点困难。 OpenCV中有很多可用的功能,但比较难的是:
1.理解可用的各种函数;
2.选择出用于你特定问题的函数。
我个人认为学习如何使用OpenCV对于任何计算机视觉爱好者来说都是必须的。因此,我决定写这篇文章,详细介绍OpenCV中的各种(常见)的功能,它们的应用,以及如何开始使用每个功能。本文中有Python代码,因此请准备好你的笔记本!
注意:本文假设你熟悉计算机视觉术语。如果你是刚接触这个主题,可以查看以下资源:
- Deep Learning for Computer Vision – Introduction to Convolution Neural Networks (CNNs)
- Build your First Image Classification Model in just 10 Minutes!
- Computer Vision using Deep Learning Course
目录
- 什么是计算机视觉?
- 为什么将OpenCV用于计算机视觉任务?
- 读,写和显示图像
- 转换颜色空间
- 调整图像大小
- 图像旋转
- 图像变换
- 简单图像阈值处理
- 自适应阈值处理
- 图像分割(分水岭算法)
- 位运算
- 边缘检测
- 图像过滤
- 图像轮廓
- 尺度不变特征变换(SIFT)
- 加速稳健特征(SURF)
- 特征匹配
- 人脸检测
什么是计算机视觉?
在我们深入了解OpenCV之前,让我快速解释一下计算机视觉是什么。对本文的其余部分将要讨论的内容有一个直观了解是很好的。
我们人类先天就有观察和感知世界的能力。接下来我们又能自然通过视觉和感知能力从周围环境中收集信息。
快速浏览上面的图片。我们用不到一秒的时间就能发现有一只猫,一条狗和一双人类的腿。而对于机器,这种学习过程变得复杂。解析图像和检测对象的过程涉及多个复杂的步骤,包括特征提取(边缘检测,形状定义等),特征分类等。
“计算机视觉是一个使机器能够像人类一样查看,识别和处理图像的深度学习领域。”
计算机视觉是目前业界最热门的领域之一。可以预见在接下来的2- 4年里将会出现大量的职位空缺。那么问题是——你准备好利用这些机会了吗?
花点时间思考一下——当你想到计算机视觉时,会想到哪些应用或产品?名单十分庞大。我们每天都会使用其中的一些!使用人脸识别解锁我们的手机,我们的智能手机相机,自动驾驶汽车等——计算机视觉无处不在。
为什么将OpenCV用于计算机视觉任务?
OpenCV,开源计算机视觉库,最初是一个英特尔的研究项目。 就其所拥有的大量功能而言,它目前是最大的计算机视觉库。
OpenCV包含超过2500种算法的实现! 它可以免费用于商业和学术目的。乐趣并没有结束! 该库具有多种语言的接口,包括Python,Java和C ++。
第一个OpenCV版本,1.0,于2006年发布,OpenCV社区从那时起实现了跨越式发展。
现在,让我们把注意力转向本文主旨——OpenCV提供的众多功能!我们将从数据科学家的角度来审视OpenCV,并了解一些使得开发和理解计算机视觉模型的任务更容易的功能。
读,写和显示图像
机器使用数字查看和处理所有内容,包括图像和文本。如何将图像转换为数字呢?——我能听到你在发问。一个词——像素值:
每个数字代表该特定位置的像素强度。在上面的图像中,我已经示出了一个灰度图像的像素值,其中每个像素仅包含一个值,即该位置处的黑色强度。
注意彩色图像对于单个像素将具有多个值。这些值表示各个通道的强度——例如,RGB图像的红色,绿色和蓝色通道。
读写图像对任何计算机视觉项目都至关重要。OpenCV库使这个功能变得更加容易。
现在,让我们看看如何使用OpenCV将图像导入我们的机器。从这里下载图像。
默认情况下,imread函数以BGR(蓝 - 绿 - 红)格式读取图像。我们可以使用imread函数中的额外标志位来读取不同格式的图像:
l cv2.IMREAD_COLOR:加载彩色图像的默认标志位;
l cv2.IMREAD_GRAYSCALE:以灰度格式加载图像;
l cv2.IMREAD_UNCHANGED:以给定格式加载图像,包括alpha通道。Alpha通道存储透明度信息——Alpha通道的值越高,像素越不透明。
转换色彩空间
色彩空间是用于以易于再现的方式表示颜色的协议。我们知道灰度图像具有单个像素值,而彩色图像包含每个像素的3个值 - 红色,绿色和蓝色通道的强度。
大多数计算机视觉用例都以RGB格式处理图像。但是,视频压缩和设备独立存储等应用——这些应用在很大程度上依赖于其他色彩空间,如色调饱和度值(HSV)色彩空间。
如你所理解的,RGB图像由不同颜色通道的颜色强度组成,即强度和颜色信息在RGB颜色空间中混合,但在HSV颜色空间中,颜色和强度信息彼此分离。这使得HSV色彩空间对亮度变化更加鲁棒。
默认情况下,OpenCV以BGR格式读取给定图像。因此,在使用OpenCV读取图像时,你需要将图像的色彩空间从BGR更改为RGB。让我们看看如何做到这一点:
调整图像大小
机器学习模型需要固定大小的输入。同样地,计算机视觉模型也是。我们用于训练模型的图像必须具有相同的尺寸。
因此如果我们通过从各种来源抓取图像来创建我们自己的数据集,这可能会成为问题。这就是调整图像大小的功能脱颖而出的地方。
使用OpenCV可以轻松扩展和缩小图像。此操作在我们训练深度学习模型时对需要将图像转换为模型的输入形状地情况非常有用。OpenCV支持不同的插值和降采样方法,可以使用以下参数实现:
INTER_NEAREST:最近邻插值
INTER_LINEAR:双向线性插值
INTER_AREA:使用像素区域关系重采样
INTER_CUBIC:4×4像素邻域上的双立方插值
INTER_LANCZOS4:8×8邻域的Lanczos插值
OpenCV的resize函数默认使用双向线性插值。
图像旋转
“你需要大量数据来训练深度学习模型”。我相信你一定在某个方面遇到这个想法。这是部分正确的——大多数深度学习算法在很大程度上依赖数据的质量和数量。
但是如果你没有足够大的数据集呢?并非我们所有人都能手动收集和标记大量图像。
假设我们正在构建一个图像分类模型,用于识别图像中存在的动物。因此,下面显示的图像都应归类为“狗”:
如果不对这些图像进行训练,该模型可能会难以将第二张图像归类为狗。所以我们该怎么办呢?
让我向你介绍一种数据增强技术。这种方法使我们能够生成更多样本来训练我们的深度学习模型。数据增强通过应用旋转,缩放,平移等图像操作,使用可用的数据样本来生成新的数据样本。这使得我们的模型对输入的变化具有鲁棒性并更好的泛化。
旋转是最常用且易于实现的数据增强技术之一 顾名思义,它涉及以任意角度旋转图像并为其提供与原始图像相同的标签。想一下你在手机中旋转图像以达到某些角度的时候——这基本上就是这个功能的作用。
图像变换
图像转换是一种几何变换,它将图像中每个对象的位置映射到最终输出图像中的新位置。 在变换操作之后,输入图像中位置(x,y)处出现的对象被移位到新位置(X,Y):
X = x + dx
Y = y + dy
这里,dx和dy是沿不同维度的相应变换。
图像变换可用于向模型添加位移不变性,因为通过变换我们可以更改图像中对象的位置,为模型提供更多多样性,从而获得更好的通用性。这在困难条件下,比如当对象不完全与图像中心对齐时,非常有效。
这种增强技术还可以帮助模型正确地对只有部分可见对象的图像进行分类。以下图为例,即使图像中没有完整的鞋子,模型也应该能够将其归类为鞋子。
该变换功能通常用于图像预处理阶段。 查看以下代码可以了解它在实际场景中的工作原理:
简单图像阈值处理
阈值处理是一种图像分割方法。它将像素值与阈值进行比较并相应地更新。OpenCV支持多种阈值变换。可以像这样定义一个简单的阈值函数:
如果Image(x,y)>阈值,则Image(x,y)= 1
否则,Image(x,y)= 0
阈值处理只能应用于灰度图像。
一个图像阈值处理的简单应用是将图像分成前景和背景。
自适应阈值处理
在自适应阈值处理中,不同的阈值用于图像的不同部分。此功能可为具有不同亮度条件的图像提供更好的结果 - 因此称为“自适应”。
Otsu的二值化方法为整个图像找到最佳阈值。它适用于双峰图像(直方图中有2个峰值的图像)。
图像分割(分水岭算法)
图像分割是将图像中的每个像素分类到某个类的任务。例如,将每个像素划分到前景或背景。图像分割对于从图像中提取有用部分很重要。
分水岭算法是一种经典的图像分割算法。它将图像中的像素值视为地形图。为了找到对象边界,它将初始标记作为输入。然后该算法开始从标记开始一直输入数据到盆地,直到标记在物体边界处相遇。
假设我们有一个有多个盆地的地形图。现在,如果我们用不同颜色的水填充不同的盆地,那么不同颜色的交叉处将为我们提供物体边界。这是分水岭算法的直观表达。
位运算
位运算包括AND,OR,NOT和XOR。你可能会从编程课程中记得它们!在计算机视觉中,当我们具有模板图像并且想要将该模板应用于另一图像以提取感兴趣的区域时,这些运算非常有用。
在上图中,我们可以看到使用分水岭算法计算的输入图像及其分割掩模。然后,我们应用了按位“与”运算来从图像中移除背景并从图像中提取相关部分。效果非常棒!
边缘检测
边缘是图像中图像亮度急剧变化或具有不连续性的点。这种不连续性通常对应于:
l 深度不连续
l 表面取向不连续
l 材料属性的变化
l 场景照明的变化
边缘是图像的非常有用的特征,可用于不同的应用,例如图像中的对象分类和本地化。甚至深度学习模型也计算边缘特征以提取关于图像中存在的对象的信息。
边缘与轮廓不同,因为它们与对象无关,而是表示图像像素值的变化。边缘检测可用于图像分割,甚至可用于图像锐化。
图像过滤
在图像过滤中,使用其相邻值更新像素值。但这些值如何进行首次被更新呢?
嗯,有许多方法可以更新像素值,例如从相邻值中选择最大值,使用相邻值的平均值等。每种方法都有自己的用途。例如,对邻域中的像素值求平均值被用于图像模糊。
高斯滤波也用于图像模糊,基于它们与相关像素的距离赋予相邻像素不同的权重。
对于图像过滤,我们使用内核。内核是具有不同形状的数字的矩阵,例如3 x 3,5 x 5等。内核用于计算图像的一部分的点积。在计算像素的新值时,内核中心与像素重叠。相邻像素值与内核中的相应值相乘。计算出的值被分配给与内核中心重合的像素。
在上面的输出中,右边的图像显示了在输入图像上应用高斯核的结果。我们可以看到原始图像的边缘被抑制。具有不同sigma值的高斯核被广泛用于计算图像的高斯差。这是特征提取过程中的重要步骤,因为它减少了图像中存在的噪声。
图像轮廓
轮廓是点或线段的闭合曲线,表示图像中对象的边界。轮廓基本上是图像中对象的形状。
与边缘不同,轮廓不是图像的一部分。它们对应于图像中对象形状的点和线段的抽象集合。
我们可以使用轮廓来计算图像中的对象数量,基于形状对对象进行分类,或者从图像中选择特定形状的对象。
尺度不变特征变换(SIFT)
关键点是你在处理图像时应该注意的概念。 这些基本上是图像中的有用点。关键点类似于给定图像的特征。
它们是定义图像中有用内容的位置。关键点很重要,因为无论图像如何被修改(旋转,收缩,扩展,失真),我们总会找到相同的图像关键点。
尺度不变特征变换(SIFT)是一种非常流行的关键点检测算法。它包括以下步骤:
l 尺度空间极值检测
l 关键点本地化
l 方向分配
l 关键点描述符
l 关键点匹配
从SIFT中提取的特征可用于图像拼接,目标检测等应用。下面的代码和输出显示了如何使用SIFT计算关键点及其方向。
加速稳健特征(SURF)
加速稳健特征(SURF)是SIFT的增强版本。它的工作速度更快,对图像变换更具鲁棒性。 在SIFT中,使用高斯拉普拉斯算子来近似比例空间。等等——听起来太复杂了。什么是高斯拉普拉斯算子?
拉普拉斯算子是用于计算图像边缘的核。 拉普拉斯算子核通过近似图像的二阶导数来工作。 因此,它对噪声非常敏感。我们通常在拉普拉斯核之前对图像使用高斯核,因此给它命名为高斯拉普拉斯算子。
在SURF中,使用盒式滤波器(内核)计算高斯拉普拉斯算子。带有盒式滤波器的卷积可以对不同尺度并行完成,这是提高SURF速度的潜在原因(与SIFT相比)。在SURF中还有其他类似的改进——我建议通过这篇论文(https://www.vision.ee.ethz.ch/~surf/eccv06.pdf )深入了解这一点。
特征匹配
使用SIFT或SURF从不同图像提取的特征可以用于匹配找到存在于不同图像中的类似对象/图案。OpenCV库支持多种特征匹配算法,如强化匹配,knn特征匹配等。
在上图中,我们可以看到从原始图像(左侧)提取的关键点与其旋转版本的关键点匹配。这是因为使用SIFT提取的特征,对于这种变换是不变的。
人脸检测
OpenCV支持基于haar级联的目标检测。Haar级联是基于机器学习的分类器,可以计算图像中的边缘,线条等不同的特征。然后,这些分类器使用多个正样本和负样本进行训练。
OpenCV Github仓库中提供了针对不同对象(如面部,眼睛等)的训练分类器,你还可以为任何对象训练自己的haar级联。
务必浏览下面这篇教你如何使用OpenCV构建视频人脸检测模型的很棒的文章:
l 使用深度学习构建视频人脸检测模型(OpenCV实现) (https://www.analyticsvidhya.com/blog/2018/12/introduction-face-detection-video-deep-learning-python/ )
如果你希望从头开始学习人脸检测的概念,那么本文你应该感兴趣。
结束语
OpenCV是一个真正的计算机视觉任务的全能计算库。我希望你在你的机器上试用了上述所有代码 - 学习计算机视觉的最佳方法是自己应用它。我鼓励你尽可能多地使用OpenCV构建自己的应用程序和实验。
OpenCV不断为机器学习中的最新算法添加新模块,你可以查看他们的Github存储库并熟悉实现。你甚至可以为库做出贡献,这是学习和与社区互动的好方法。
你是计算机视觉的新手吗?从这里开始你的旅程吧:
你还可以在Analytics Vidhya的Android APP上阅读这篇文章。