机器学习系统设计笔记8--图像的分类
条评论最近看完了 Willi Richert的《机器学习系统设计》。书虽然有点薄但也比较全,内容感觉有点偏文本处理,里面介绍了一些文本处理的方法和工具。综合起来看作为机器学习入门还是挺不错的,这里就简单记一下我做的笔记,方便回顾。书中的代码可以通过它说到的网站下载,这里是第8部分笔记。
第十章 图像的分类
机器学习有很多关于图像分析和计算机视觉方面的研究。这一章的重点其实是用mahotas包对图像进行预处理和特征提取,对于机器学习方法介绍的并不是太多,mahotas程序包是这本书的一个作者开发的。除了这个工具包外,还有scikit-image(Skimage),Scipy中的ndimage(n维图像)模块,以及OpenCV。
图像处理
mahotas的的使用如下,首先是读取和显示图片:
1 | import mahotas as mh |
阈值
卡阈值是一种非常简单的操作:我们对像素值变化,大于阈值的为1,小于阈值的为0。mahotas实现了一些选择阈值的方法。其中一个叫做Otsu,该方法的第一个必要步骤就是用rgb2gray把图像转换为灰度图。
1 | image = mh.colors.rgb2gray(image, dtype=np.uint8) |
计算阈值:
1 | thresh = mh.thresholding.otsu(image) |
高斯模糊
对图像进行模糊化经常被用于降噪,可以对后续的处理有所帮助,在mahotas中,只需要一个函数调用即可:
1 | image = mh.colors.rgb2gray(image) |
注意,这里并没有把灰度图转化成无符号整数,只是利用了浮点数结果。gaussian_filter函数的第二个参数是这个滤波器的大小(滤波器的标准差)。较大的值会导致结果更为模糊。通过模糊化再进行阈值分析,结果可能会含有更少的噪声。
加入椒盐噪声
加入噪声可能测试分类器对有噪声图像的处理能力,椒是黑色噪声值,盐是白色噪声值。
1 | salt = np.random.random(image.shape) > .975 |
聚焦中心
最后一个例子显示了如何用Numpy操作和一些滤波混合起来:
1 | # 首先把它切分成几个颜色通道 |
模式识别
对于图像的分类,如果直接把每个像素值都当作特征放到机器学习算法中,可能效果并不好,因为每个像素和最终结果之间的关系是非常间接的。传统的方法是从图像中计算特征,然后把这些特征用于分类。有一些方法可以直接对像素进行操作,他们有特征计算子模块。他们甚至试图自动从图像里面学出好的特征,这些都是当今学术界正在研究的课题。由于历史的原因,图像分类又叫做模式识别然而它就是将分类方法应用于图像。
特征设计和提取
使用mahotas可以很容易的提取图像的特征。有一个子模块叫做mahotas.features ,包含了一些特征计算函数。
一个很常用的特征集合叫做Haralick纹理特征。这些特征是基于纹理的:它们会对平滑的图像和带有模式的图像进行区分。用mahotas很容易计算这些特征:
1 | haralick_features = np.mean(mh.features.haralick(image),0) |
mh.features.haralick函数返回了一个4*13的数组,第一维表示特征的四个方向(上,下,左,右)。如果对方向不感兴趣,也可以对整体计算平均值。
mahotas还有一些其他的特征集合。线性二元模式(linear binary pattern)是另一个基于纹理的特征集合,它对光亮变化非常健壮。
设计一个新的特征并不是很难的事情,为了不同的图像分类目的,不同的特征表现可能差异很大。我们介绍一个边界寻找的例子,并把它加到特征中去,我们使用sobel滤波。从数学上说,我们用两个矩阵对图像滤波(求卷积);竖向矩阵如下所示
$$
\begin{pmatrix}
1 & 0 & 1 \\
-2 & 0 & -2 \\
1 & 0 & 1 \\
\end{pmatrix}
$$
横向矩阵
$$
\begin{pmatrix}
1 & -2 & 1 \\
0 & 0 & 0 \\
1 & -2 & 1 \\
\end{pmatrix}
$$
然后我们把结果的平方相加,得到对每一点锐度的一个综合估计。直接用mahotas进行sobel滤波:
1 | filtered = mh.sobel(image, just_filter = True) |
局部特征表示
在计算机视觉领域一个较新的进展就是基于局部特征的方法。*局部特征(local feature)是在图像的一小块区域内计算出来的特征。mahotas支持这类特征中的一种:加速稳健特征(Speeded Up Robust Feature)又叫做SURF;还有一些其他的特征,如尺度不变特征变换(Scale-Invariant Feature Trandform, SIFT)*。这些局部特征对于旋转和光照变化十分稳健。
在使用这些特征的时候,我们需要确定在哪里计算它们。这里有3个经常采用的选项:
- 随机计算;
- 在一个格子里计算;
- 检测图像中的兴趣区域(这种技术叫做关键点检测(keypoint detection))
mahotas对这三种方式都提供了支持。如果你确定的兴趣点可以和图像里的重要区域相对应,那么兴趣点检测的效果将会是最好的。通常他们对人造图像的效果比自然风景图像要好。人造景观有较强的角度边界,以及高对比度的区域。这些通常会被自动检测器识别为兴趣区域。
1 | from mathotas.features import surf |
我们不能直接把这些描述符传进机器学习分类器中,要使用图像中的描述符,可以采用词袋模型:把图像中看起来相似的区域聚成一组,把它们叫做视觉词语。词语个数一般对算法的最终效果并没有很大影响。不过,如果这个数字特别小,那么系统的效果不会很好,特别多的时候,整个系统表现也不会很好。在两个极端之间,可以试的区间会很大,经验法则,如果你有很多很多图片,采用诸如256,512,1024这样的数值应该可以得到不错的效果。
1 | alldescriptors = [] |
上面得到的features就是最后算出来的特征空间,使用features进行分类可以获得一定的性能提升。
本文标题:机器学习系统设计笔记8--图像的分类
文章作者:throneclay
发布时间:2015-10-20
最后更新:2022-08-03
原始链接:http://blog.throneclay.top/2015/10/20/mldesgin10/
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN 许可协议。转载请注明出处!