介绍
在本教程中,我们将学习如何使用Python语言执行图像处理。我们不会局限于单个库或框架;但是,我们将最常使用的是Open CV库。我们将先讨论一些图像处理,然后再继续介绍可以方便使用图像处理的不同应用程序/场景。
什么是图像处理?
重要的是要了解图像处理的确切含义,以及在深入了解图像处理的作用之前,图像处理在大图中的作用是什么。图像处理最常被称为“数字图像处理”,而经常使用的领域是“计算机视觉”。请勿混淆。图像处理算法和计算机视觉(CV)算法都将图像作为输入。但是,在图像处理中,输出也是图像,而在计算机视觉中,输出可能是有关图像的某些特征/信息。
我们为什么需要它?
我们收集或生成的数据大部分是原始数据,即由于多种可能的原因,不适合直接在应用程序中使用。因此,我们需要先对其进行分析,执行必要的预处理,然后再使用它。
例如,假设我们正在尝试构建cat分类器。我们的程序将图像作为输入,然后告诉我们图像是否包含猫。建立该分类器的第一步是收集数百张猫图片。一个普遍的问题是,我们抓取的所有图片都不会具有相同的尺寸/尺寸,因此在将它们输入模型进行训练之前,我们需要将所有尺寸调整/预处理为标准尺寸。
这只是图像处理对于任何计算机视觉应用必不可少的众多原因之一。
先决条件
在继续进行之前,让我们讨论一下需要了解的内容,以便轻松地学习本教程。首先,您应该掌握任何语言的基本编程知识。其次,您应该知道什么是机器学习以及它如何工作的基础,因为本文中我们将使用一些机器学习算法进行图像处理。另外,如果您在继续学习本教程之前对Open CV有任何了解或基础知识,这将对您有所帮助。但这不是必需的。
为了遵循本教程,您一定要知道的一件事是图像在内存中的准确表示方式。每个图像由一组像素表示,即像素值矩阵。对于灰度图像,像素值的范围是0到255,它们代表该像素的强度。例如,如果您具有20 x 20尺寸的图像,则将以20x20的矩阵(总共400个像素值)表示。
如果要处理彩色图像,则应该知道它将具有三个通道-红色,绿色和蓝色(RGB)。因此,单个图像将有三个这样的矩阵。
安装
注意:由于我们将通过Python使用OpenCV,因此隐含的要求是您的工作站上已经安装了Python(版本3)。
windows
$ pip install opencv-python
苹果系统
$ brew install opencv3 --with-contrib --with-python3
Linux
$ sudo apt-get install libopencv-dev python-opencv
要检查安装是否成功,请在Python Shell或命令提示符中运行以下命令:
import cv2
您应该知道的一些基本知识
在我们继续在应用程序中使用图像处理之前,重要的是要了解哪种操作属于此类,以及如何进行这些操作。这些操作以及其他操作将在以后的应用程序中使用。
对于本文,我们将使用以下图像:
注意:为了在本文中显示图像,已对图像进行了缩放,但是我们使用的原始大小约为1180x786。
您可能已经注意到图像当前是彩色的,这意味着它由三个颜色通道表示,即红色,绿色和蓝色。我们将图像转换为灰度图像,并使用下面的代码将图像分为单独的通道。
查找图像细节
在使用imread()
函数加载图像后,我们可以检索有关图像的一些简单属性,例如像素数和尺寸:
print("Image Properties") print("- Number of Pixels: " + str(img.size)) print("- Shape/Dimensions: " + str(img.shape))
输出:
Image Properties - Number of Pixels: 2782440 - Shape/Dimensions: (1180, 786, 3)
将图像分成单独的通道
现在,我们将使用OpenCV将图像分为红色,绿色和蓝色分量,显示它们:
cv2_imshow(red) # 显示红色通道 cv2_imshow(blue) #显示蓝色通道 cv2_imshow(green) #显示绿色通道 cv2_imshow(img_gs) # 显示灰色版本
为简便起见,我们只显示灰度图像。
灰度图像:
图像阈值
阈值的概念非常简单。如上面在图像表示中所讨论的,像素值可以是0到255之间的任何值。假设我们希望将图像转换为二进制图像,即为像素分配0或1的值。为此,我们可以执行阈值化。例如,如果阈值(T)值为125,则所有值大于125的像素将被分配值为1,所有值小于或等于该值的像素将被分配值为0。通过代码获得更好的理解。
用于阈值的图像:
import cv2 cv2_imshow(threshold)
如您所见,在生成的图像中,已经建立了两个区域,即黑色区域(像素值0)和白色区域(像素值1)。事实证明,我们设置的阈值正好在图像的中间,这就是为什么在此处划分黑白值的原因。
应用领域
#1:去除图像中的噪点
既然您已经基本了解了什么是图像处理及其用途,那么让我们继续学习它的一些特定应用程序。
在大多数情况下,我们收集的原始数据中有噪点,即使图像难以感知的不良特征。尽管这些图像可以直接用于特征提取,但是算法的准确性会受到很大影响。这就是为什么在将图像处理传递给算法之前对其进行图像处理以获得更好的准确性的原因。
噪声有很多不同的类型,例如高斯噪声,胡椒噪声等。我们可以通过应用滤镜来去除图像中的噪声,或者将噪声降到最低,或者至少将其影响降到最低。滤波器也有很多选择,每个都有不同的强度,因此对于特定类型的噪声来说是最佳选择。
为了正确理解这一点,我们将在上面考虑过的玫瑰图像的灰度版本中添加“盐和胡椒”噪声,然后尝试使用不同的滤镜从嘈杂的图像中去除该噪声,然后看看哪个是最好的-适合那种类型。
import numpy as np cv2.imwrite('sp_05.jpg', sp_05)
好吧,我们在玫瑰图像中添加了噪点,现在看起来是这样:
嘈杂的图像:
现在让我们在其上应用不同的滤波器,并记下我们的观察结果,即每个滤波器降低噪声的程度。
带有锐化内核的算术滤波器
# 对噪音图像进行滤波 sharpened_img = cv2.filter2D(sp_05, -1, kernel_sharpening) cv2_imshow(sharpened_img)
通过对带有噪声的图像应用算术滤波器,生成的图像如下所示。与原始灰度图像进行比较后,我们可以看到它使图像亮度过高,也无法突出玫瑰上的亮点。因此,可以得出结论,算术滤波器无法去除噪声。
算术滤波器输出:
中点滤波器
print("\n\n---Effects on S&P Noise Image with Probability 0.5---\n\n") midpoint(sp_05)
将中点滤镜应用到噪声的图像上的结果图像如下所示。与原始灰度图像进行比较后,我们可以看到,就像上面的核方法一样,图像亮度过高。但是,它可以突出玫瑰上的亮点。因此,可以说它是比算术滤波器更好的选择,但仍然不能完全恢复原始图像。
谐谐波均值滤波器
注意:可以在网上轻松找到这些过滤器的实现,并且它们的工作原理超出了本教程的范围。我们将从抽象/更高的层次来研究应用程序。
print("\n\n--- Effects on S&P Noise Image with Probability 0.5 ---\n\n") cv2_imshow(contraharmonic_mean(sp_05, (3,3), 0.5))
下面显示了在噪声下对图像应用Contraharmonic Mean Filter 所得到的图像。与原始灰度图像进行比较后,我们可以看到它已复制了几乎与原始图像完全相同的图像。其强度/亮度级别相同,并且也突出了玫瑰上的亮点。因此,我们可以得出结论,对谐波均值滤波器在处理盐和胡椒噪声方面非常有效。
既然我们已经找到了从嘈杂的图像中恢复原始图像的最佳过滤器,那么我们可以继续下一个应用程序了。
2:使用Canny Edge Detector进行边缘检测
到目前为止,我们一直在使用的玫瑰图像具有恒定的背景,即黑色,因此,对于该应用程序,我们将使用不同的图像以更好地显示算法的功能。原因是如果背景恒定,则边缘检测任务将变得非常简单,我们不希望这样做。
我们在本教程的前面讨论了cat分类器,让我们向前看这个示例,看看图像处理如何在其中发挥不可或缺的作用。
在分类算法中,首先会扫描图像中的“对象”,即,当您输入图像时,算法会在该图像中找到所有对象,然后将它们与您要查找的对象的特征进行比较。如果是猫分类器,它将对图像中找到的所有对象与猫图像的特征进行比较,如果找到匹配项,它将告诉我们输入图像包含猫。
由于我们以cat分类器为例,因此公平地使用cat图像是公平的。下面是我们将使用的图像:
用于边缘检测的图像:
import cv2 import numpy as np from matplotlib import pyplot as plt #显示两个图片 plt.show()
边缘检测输出:
如您所见,图像中包含对象的部分(在这种情况下是猫)已通过边缘检测点到/分开了。现在您必须要知道,什么是Canny Edge Detector,它是如何实现的?现在让我们讨论一下。
要理解上述内容,需要讨论三个关键步骤。首先,它以与我们之前讨论的相似方式对图像执行降噪。其次,它在每个像素处使用一阶导数来查找边缘。其背后的逻辑是存在边缘的点处,强度会突然变化,这会导致一阶导数的值出现尖峰,从而使该像素成为“边缘像素”。
最后,它执行磁滞门限;上面我们说过,边上的一阶导数的值有一个峰值,但是我们没有说明峰值需要多高才能将其分类为边缘-这称为阈值!
在本教程的前面,我们讨论了简单的阈值化。磁滞阈值是对此的改进,它使用两个阈值而不是一个。其背后的原因是,如果阈值太高,我们可能会错过一些实际边缘(真负值),而如果阈值太低,我们会得到很多归类为实际上不是边缘的边缘(假正值)的点。)。将一个阈值设置为高,将一个阈值设置为低。所有高于“高阈值”的点都被标识为边缘,然后评估所有高于低阈值但低于高阈值的点;被标识为边的点附近或与之相邻的点也被标识为边,其余部分被丢弃。
这些是Canny Edge Detector算法用于识别图像边缘的基本概念/方法。
结论
在本文中,我们学习了如何在Windows,MacOS和Linux等不同平台上安装OpenCV(用于Python图像处理的最流行的库),以及如何验证安装是否成功。
我们继续讨论了什么是图像处理及其在机器学习的计算机视觉领域中的用途。我们讨论了一些常见的噪声类型,以及如何在应用程序中使用图像之前使用不同的滤镜将其从图像中去除。
此外,我们了解了图像处理如何在诸如“对象检测”或“分类”之类的高端应用中发挥不可或缺的作用。请注意,本文只是冰山一角,不可能在单个教程中介绍。