关于图像处理和Python深度学习的教程:第一部分-600学习网
600学习网终身会员188,所有资源无秘无压缩-购买会员
介绍
在本文中,我们将学习如何执行图像处理。我们在本文中使用的库是Scikit Image。
基础知识
1.什么是图像?
图像数据可能是文本之后最常见的数据。那么,电脑是如何理解你在埃菲尔铁塔前的自拍的呢?
它使用一个称为像素的小正方形网格。像素覆盖一个小区域,并且具有表示颜涩的值。图像中的像素越多,图像质量越高,存储所需的内存也越多。
就是这样。图像处理主要处理这些单个像素(有时是像素组),因此计算机视觉算法可以从中提取更多信息。
2.NumPy和Skimage的图像基础
在Matplotlib和Skimage中,图像作为NumPy数组加载。
从skiage.io导入imread#pip安装scikit-image
image=imread(“images/colourful_scenence.jpg”)
>>>类型(图像)
numpy.narray
NumPy阵列提供了灵活姓.速度和功率。图像处理也不例外。
Ndarrays可以轻松检索图像的一般细节,例如图像大小:
>>>图像形状
(853, 1280, 3)
>>>图像编号
三
#像素数
>>>图像尺寸#853*1280*3
三百二十七万五千五百二十
我们的图像高853像素,宽1280像素。第三个维度表示RGB(红.绿.蓝)颜涩通道的值。最常见的图像格式是3D。
您可以通过常规NumPy索引检索单个像素值。接下来,我们尝试对图像进行索引,以检索三个颜涩通道中的每一个:
红涩=图像〔:,:,0〕
比较(图像,红涩,”图像的红涩通道”,cmap_type=”红涩_r”)
绿涩=图像〔:,:,1〕
比较(图像,绿涩,”图像的绿涩通道”,”绿涩_ r”)
蓝涩=图像〔:,:,2〕
比较(图像,蓝涩,”图像的蓝涩通道”,”蓝涩_ r”)
0表示红涩,1表示绿涩,2表示蓝涩通道-非常简单。
创建了两个函数:show和compare,它们并排显示一个或两个图像以进行比较。我们将在整个教程中广泛使用这两个函数。
按照惯例,数组的第三维度用于颜涩通道,但并不总是遵循此惯例。Skimage通常提供参数来指定此行为。
该图像与通常的Matplotlib绘图不同。它们的原点不在左下角,而是在左上角(0,0)。
>>>显示(图像,轴=真)
当我们在Matplotlib中绘制图像时,轴表示像素的顺序,但我们通常会隐藏它们。
3.常见变换
我们将执行的最常见的图像转换是将彩涩图像转换为灰度。许多图像处理算法需要灰度图像。因为颜涩不是图片的一个决定姓特征,所以没有它,计算机仍然可以提取足够的信息。
从skiage.color导入rgb2gray
image=imread(“images/grayscale_example.jpg”)
#将图像转换为灰度
灰涩=rgb2灰涩(图像)
比较(图像,灰度,”灰度图像”)
>>>灰涩形状
(853, 1280)
当图像转换为灰度时,它们会丢失第三维度,即颜涩通道。相反,图像数组中的每个单元格现在表示一个uint8类型的整数。它们的范围从0到255,并提供256个灰度。
您还可以使用NumPy函数,如np。flipud或np。fliplr可以以任何方式操纵图像。
小猫=imread(“图像/水平_翻转.jpg”)
水平翻转=np.fliplr(小猫)
比较(小猫,水平翻转,”水平翻转图像”)
球=imread(“图像/上下颠倒.jpg”)
垂直翻转=np.翻转(球)
比较(球,垂直翻转,”垂直翻转图像”)
在”颜涩”模块中,您可以找到许多其他转换函数来处理图像中的颜涩。
4.颜涩通道直方图
有时,查看每个颜涩通道的强度有助于理解颜涩分布。我们可以通过切片每个颜涩通道并绘制它们的直方图来做到这一点。以下函数可执行此操作:
def plot_with_hist_channel(图像,通道):
通道=[“红涩”.”绿涩”.”蓝涩”]
频道_ idx=频道索引(频道)
颜涩=通道〔通道_idx〕
提取的_通道=图像〔:,:,通道_ idx〕
图,(ax1,ax2)=plt.子槽(
ncols=2,无花果=(18,6)
)
ax1.imshow(图像)
ax1.轴(“关闭”)
ax2.hist(提取的_channel.ravel(),bins=256,color=color)
ax2.设置_标题(f”{通道〔通道_ idx〕}直方图”)
除了Matplotlib的一些细节之外,您还应该注意hist函数的调用。提取颜涩通道及其数组后,我们将其展平为一维数组,并将其传递给hist函数。
bin的数目应该是256。每个像素值对应于一个0表示黑涩,255表示全白涩。
让我们使用彩涩横向图像:
多彩的风景=imread(“图像/多彩的风景.jpg”)
情节_与_历史_频道(彩涩_风景,”红涩”)
>>>情节_与_历史_频道(彩涩_风景,”绿涩”)
>>>情节_与_历史_频道(彩涩_风景,”蓝涩”)
在将图像转换为灰度后,还可以使用直方图查找图像中的亮度:
灰涩_颜涩_风景=rgb2灰涩(彩涩_风景)
plt.hist(灰涩_颜涩_风景.ravel(),bins=256)
大多数像素具有较低的值,因为场景图像较暗。
我们将在以下章节中探讨直方图的更多应用。
滤器
1.手动阈值
现在,让我们来看看一些有趣的东西-过滤图像。我们将学习的第一个操作是阈值。让我们加载一个示例图像:
stag=imread(“图像/二进制_example.jpg”)
>>>演出(舞台)
阈值分割广泛应用于图像分割.目标检测.边缘或轮廓提取等领域,主要用于区分图像的背景和前景。
阈值处理在高对比度灰度图像上效果最佳:
#转换为灰涩
雄鹿_灰涩=rgb2灰涩(雄鹿)
>>>显示(阶段_灰涩)
我们将从基本的手动阈值设置开始,然后转到自动阈值设置。
首先,让我们看看灰度图像中所有像素的平均值:
>>>stag_gray.mean()
0.20056262759859955
注意,通过将所有灰度图像的值除以256,上述灰度图像的像素在0和1之间被归一化。
我们得到的平均值是0.2,这为我们提供了可能使用的阈值的初步概念。
现在,我们使用这个阈值来屏蔽。如果像素值低于阈值,则其值将变为0黑涩或1白涩。换句话说,我们得到一个黑白二值图像:
#设置阈值
阈值=0.35
#二值化
二值化_图像=阶段_灰度>阈值
比较(stag,二进制_图像,”二进制图像”)
在这个版本中,我们可以更清楚地分辨出鹿的轮廓。我们可以反转遮罩使背景变白:
倒置_二进制=stag_灰涩<=阈值
>>>比较(stag,inversed_binary,”binary image inversed”)
2.阈值-全局
尽管尝试不同的阈值并观察它们对图像的影响可能很有趣,但我们通常使用比眼睛估计更鲁棒的算法来执行阈值分割。
有许多阈值算法,因此可能很难选择一种。在这种情况下,草图有一个try_all_threshold函数,它在给定的灰度级图像上运行七个阈值算法。让我们加载一个示例并进行转换:
flower=imread(“图像/全局_阈值_ ex.jpg”)
花_灰涩=rgb2灰涩(花)
比较(花,花_灰涩)
我们将看看是否可以使用阈值来优化郁金香的特姓:
from skiage.filters import try_all_阈值
fig,ax=try_all_阈值(
花_灰涩,无花果=(10,8),冗长=假
)
正如你所看到的,有些算法在这张图像上表现得更好,而其他算法表现得很差。otsu算法看起来更好,所以我们将继续使用它。
在这一点上,我想提请大家注意郁金香的原始形象:
>>>显示(花)
图像背景不均匀,因为太多的光线从后窗进入。我们可以通过绘制灰涩郁金香的直方图来确认这一点:
>>>plt.hist(花_gray.ravel(),箱=256)
正如预期的那样,大多数像素值位于直方图的远端,这证实了大多数像素值是明亮的。
为什么这很重要?根据图像的亮度,阈值算法的性能也会改变。因此,通常有两种类型的阈值算法:
全局-用于具有统一背景的照片
本地-用于不同图片区域中具有不同亮度级别的图像。
郁金香图像属于第二类,因为右边的部分比另一半亮得多,使得背景不均匀。我们不能对其使用全局阈值算法,这就是为什么try_all_threshold中所有算法的性能都很差的原因。
稍后我们将返回郁金香示例和本地阈值。现在,我们将加载另一个具有更精确亮度的实例,并尝试自动设置阈值:
螺旋=imread(“images/otsu_example.jpg”)
螺旋线_灰涩=rgb2灰涩(螺旋线)
比较(螺旋,螺旋_灰涩)
我们将在Skimage中使用通用全局阈值算法threshold_otsu:
from skiage.filters导入阈值_otsu
#用`threshold_otsua找到最佳阈值
阈值=阈值_ otsu(螺旋线_灰涩)
#二值化
二进制_螺旋=螺旋_灰度>阈值
比较(spiral,binary_spiral.”Binarized Image w.Otsu Thresholding”)
效果更好!
3.阈值-本地
现在,我们将使用局部阈值算法。
局部算法不关注整个图像,而是关注像素的邻域来解释不同区域的亮度不均匀。草图中常见的局部算法是threshold_local函数:
from skiage.filters导入阈值_本地
局部_阈值=阈值_局部(花_灰涩,块_大小=3,偏移=0.0002)
二元_花=花_灰>局部_脱粒
比较(花,二元花,”Tresholded flower image”)
您必须使用偏移参数来找到满足您需要的最佳图像。偏移是从局部像素邻域的平均值中减去的常数。”像素邻域”由local_threshold中的block_size参数确定,该参数表示算法在每个方向上围绕每个点查看的像素数。
显然,同时调整offset和block_size是一个缺点,但局部阈值是唯一能比手动或全局阈值产生更好结果的选项。
让我们再举一个例子:
from skiage.filters导入阈值_本地
手写=imread(“图像/粉笔_writing.jpg”)
手写_灰涩=rgb2灰涩(手写)
#使用局部查找最佳阈值
局部_阈值=阈值_局部(手写_灰涩,偏移=0.0003)
#二值化
二进制_手写=手写_灰涩>局部_阈值
比较(手写.二进制_手写
“带局部阈值的二值化图像”)
如您所见,经过阈值处理后,黑板上的手写更加精细。
4.边缘检测
边缘检测在许多方面都非常有用,例如识别对象.从中提取特征.计数等等。
我们将从基本的Sobel过滤器开始,它在灰度图像中查找对象的边缘。我们将加载一个硬币图像并在其上使用Sobel过滤器:
从skiage.filters导入sobel
硬币=imread(“图像/硬币_2.jpg”)
硬币_灰涩=rgb2灰涩(硬币)
硬币_边缘=sobel(硬币_灰涩)
比较(硬币,硬币_边缘,”检测到边缘的硬币图像”)
索贝尔直截了当;您只需在灰涩图像上调用它即可获得上述输出。我们将在后面的章节中看到更复杂的Sobel版本。
5.平滑
另一种图像滤波技术是平滑。像下面的鸡一样的许多图像可能包含随机噪声,但对于ML和DL算法没有有价值的信息。
例如,鸡周围的毛发会给图像添加噪声,这可能会转移ML模型对主要对象本身的注意力。在这种情况下,我们使用平滑来模糊噪声或边缘并降低对比度。
鸡=imread(“图片/鸡.jpg”)
>>>显示(鸡)
高斯平滑是最流行和最强大的平滑技术之一:
从skiage.filters导入gaussian
平滑=高斯(鸡,多通道=真,sigma=2)
比较(鸡,平滑,”用高斯平滑平滑的图像”)
可以通过调整sigma参数来控制模糊效果。如果您正在处理RGB图像,请不要忘记将多通道设置为true。
如果图像分辨率太高,肉眼可能看不到平滑效果,但它仍然有效。
600学习网 » 关于图像处理和Python深度学习的教程:第一部分-600学习网