机器学习中的图像处理2025年3月17日 | 阅读18分钟 图像处理涉及对图像进行操作和分析,以增强其质量、提取特征或识别模式。传统的图像处理技术依赖于预定义的规则和算法来执行特定任务,例如边缘检测、图像分割或对象识别。然而,当处理复杂多样的视觉数据时,这些技术经常会遇到局限性。 另一方面,机器学习为图像处理提供了一种更灵活、更自适应的方法。通过在大量标记图像数据集上训练算法,机器学习模型可以自动学习识别模式并提取相关特征。这种从数据中学习并适应新情况的能力,使机器学习成为图像分析和处理的强大工具。 机器学习在图像处理中的关键应用之一是目标检测和识别。通过在包含感兴趣对象(如汽车、人物或建筑物)的标记图像上训练模型,机器学习算法可以学会识别和定位新图像中的这些对象。这种能力在监控等领域具有重要意义,因为自动对象检测可以协助识别潜在威胁或异常情况。 机器学习在图像处理中的另一个应用是图像分类。通过在不同类别(如动物、风景或医学图像)的标记图像上训练模型,机器学习算法可以学会将新图像分类到相应的类别中。这种能力在医疗保健等领域尤其有用,因为准确的自动图像分类可以帮助疾病诊断、医学影像分析和治疗计划。 现在,为了便于理解,我们将尝试实现它。这里我们将进行细胞核检测的图像处理。 代码 导入库读取图像输出 ![]() 输出 ![]() 图像以 BGR(蓝-绿-红)色彩空间进行解释,这意味着图像中的每个像素都由三个值表示:蓝色强度、绿色强度和红色强度。当在 OpenCV 中读取图像时,此色彩空间是默认选择。 在 BGR/RGB 色彩空间中,红色、绿色和蓝色的特定组合用于创建各种颜色。这三种原色混合在一起可以生成由它们各自值形成的三角形内的任何色度。简单来说,您可以将 RGB 颜色视为通过混合三种彩色光:红色、绿色和蓝色产生的各种颜色。通过调整这些原色的强度,我们可以创建和显示图像中的大量不同颜色。 基本步骤在这里,我们将实现经典的图像技术,希望能起到有用的入门作用。 这些经典的图像技术包括
处理颜色输出 ![]() 当我们从 BGR 色彩空间转换为灰度时,我们实际上减少了一个维度。之所以发生这种情况,是因为灰度表示一系列从黑色到白色的单色色调。换句话说,灰度图像仅包含各种灰色调,不包含任何颜色信息(它主要由黑色和白色组成)。 从 BGR 到灰度的转换消除了所有颜色数据,仅保留每个像素的亮度。在数字图像中,颜色使用红色、绿色和蓝色 (RGB) 值的组合显示。因此,每个像素都有三个与这些颜色通道相对应的独立亮度值。但是,在去除颜色并创建灰度图像时,需要将这三个值合并为一个值。 亮度也可以描述为明度或强度,它在一个从黑色(零强度)到白色(完全强度)的尺度上进行测量。通过将图像简化为灰度,我们简化了其表示,仅关注图像亮度的变化,而忽略存在的特定颜色。 输出 ![]() ![]() 当显示灰度图像矩阵的整个一行时,您实际上是在显示该行中每个像素的亮度或强度值。每个像素的亮度值表示其亮度级别,范围从黑色(最低强度)到白色(最高强度)。 通过可视化灰度图像矩阵的一行,您可以观察该行中像素的各种强度。这提供了对图像水平方向亮度模式和变化的洞察。它允许您专注于亮度变化,而不会被颜色信息干扰,突出灰度图像的色调值,并强调该特定行中存在的对比度和阴影。 因此,这显示了图像矩阵的整行以及每个像素对应的亮度或强度。 去除背景输出 ![]() 在强度分布中,我们可以观察到两个明显的峰值。强度值接近 0 的像素数量很多是符合预期的,因为与占主导地位的黑色背景相比,细胞核占据的图像部分较小。我们的任务是将细胞核与背景分开。根据描述性统计数据,我们预计最佳分离值为大约 20。但是,我们不应仅依赖于此类统计数据,而应采用更正式的方法,如 Otsu 方法。 Otsu 方法,以 Nobuyuki Otsu 命名,是一种用于自动基于聚类的图像阈值处理技术。它旨在通过识别最佳阈值将灰度图像转换为二值图像。该算法假定图像由两类像素组成,即前景像素(细胞核)和背景像素。它计算最小化两个类别的组合散布或类内方差的阈值,从而最大化它们之间的方差。简单来说,Otsu 方法根据像素强度的直方图分布确定将细胞核与背景分离的最佳阈值。 输出 ![]() 我们将使用 np.where 函数根据像素的强度值对其进行编码,我们可以创建一个蒙版,将所有强度值大于阈值的所有像素设置为 1,所有其他像素设置为 0。生成的蒙版将指示细胞核(编码为 1)和背景(编码为 0)之间的分离。 导出每个对象的蒙版输出 ![]() 当前生成的蒙版存在一些局限性。它未能准确检测到所有细胞核,特别是右上角的两个。此外,围绕 (500, 400) 标记的三个细胞核已合并为一个集群。问题源于较暗的细胞核的强度值低于阈值。 为了改进对单个细胞核的检测,我们需要使用更高级的技术。这些技术涉及额外的图像处理步骤,如形态学操作或自适应阈值处理。通过应用这些方法,我们可以增强分离并准确识别每个细胞核。 输出 ![]() 为了确定 Otsu 方法和 K-Means 聚类在像素级别获得的标签之间是否存在任何差异,我们可以比较标签并计算匹配标签的百分比。如果结果百分比为 1,则表示完全没有差异。 输出 ![]() 完全没有差异。 对象识别要获得细胞核总数的计数,我们可以使用 ndimage.label 函数,该函数根据像素的相互连接性来标记数组中的特征(像素)。因此,例如,如果 [1 1 1 0 0 1 1] 是我们的行向量,那么使用 ndimage.label 将得到 [1 1 1 0 0 2 2],表示行向量中有 2 个不同的对象。该函数返回标记的数组以及它找到的不同对象的数量。 输出 ![]() 输出 ![]() 输出 ![]() 图像中可能存在的细胞核比我们目前识别的要多。一些细胞核已合并在一起,导致它们被视为我们蒙版中的单个对象。此外,我们的蒙版可能未能成功检测到所有细胞核,特别是位于右上角的细胞核。有趣的是,在右上角,有两个独立的光斑被标记为不同的对象,即使它们属于同一组或集群。
通过应用 Sobel 滤波器或 Canny 边缘检测器,我们可以检测到聚集的细胞核之间的边缘。这使我们能够区分单个细胞核并根据检测到的边缘进行分离。生成的分割将能够更准确地识别和描绘每个细胞核,即使它们彼此靠近。 为了获得每个细胞核的单独蒙版,我们可以利用“stage1_train_labels.csv.zip”文件,该文件包含图像 ID 以及每个细胞核蒙版对应的游程编码 (RLE) 向量。RLE 向量表示蒙版内像素的位置。 输出 ![]() 1 表示整个图像中的 1 个此类对象(细胞核)。 游程编码RLE 或游程编码将矩阵转换为向量,并返回我们观察到对象(由 1 标识)的第一个像素的位置/起始点,并给出从该像素开始看到 1 系列的像素数量。在 ndimage.label 函数的 [1 1 1 0 0 1 1] 示例中,运行 RLE 将得到 1 3 6 2,这意味着从第 0 个像素(包含)开始的 3 个像素和从第 5 个像素开始的 2 个像素我们看到了一系列 1。 输出 ![]() 合并所有内容输出 ![]() 边缘检测边缘检测是图像处理中的一个基本概念,涉及识别图像中不同对象或区域之间的边界或边缘。它在计算机视觉、机器人和医学成像等各种领域发挥着至关重要的作用。传统的边缘检测算法,如 Sobel 算子和 Canny 边缘检测器,使用数学运算来定位快速强度变化的区域。 在这里,我们将首先使用 Sobel 滤波器。 输出 ![]() 输出 ![]() Sobel 滤波器在识别图像中的独立对象方面比 Otsu/K-Means 表现更好。它成功检测到了右上角的两个细胞核以及 (530,410) 区域附近的两个小细胞核。但是,仍有改进的空间,因为它合并了该区域中三个重叠细胞核中的两个,而不是将它们识别为独立的物体。 输出 ![]() 我们现在将使用 Canny 边缘检测器,它是一种更智能的 Sobel 滤波器。 输出 ![]() Canny 边缘检测器检测到了细胞核内的梯度,这似乎有点过多。但是,如果我们只关注提取外部轮廓并使用它们来创建蒙版,我们可以更准确地捕获感兴趣的区域。值得注意的是,这里仍然存在与 Sobel 滤波器遇到的类似问题。然而,Canny 边缘检测器生成了一个由二值(0 和 255)组成的修改后的图像矩阵,简化了检测到的边缘的表示。 输出 ![]() 输出 ![]() Canny 边缘检测器成功检测到大多数细胞核,但未能获得每个细胞核的完整蒙版。调整 cv2.Canny() 函数中的 minval 和 maxval 参数可能会改善结果,并考虑到被处理图像的特定特征。canny_mask 矩阵输出与 ndimage.labels 函数兼容,该函数用于识别连接的组件。然而,生成每个细胞核的完整蒙版至关重要,以确保我们检测到的对象不超过图像中实际存在的对象数量。 输出 ![]() 输出 ![]() 强度值等于 1 的像素数量已减少。这种减少归因于平滑过程。我们使用局部滤波器(具体来说是一个所有值都设置为 1/9 的 3x3 矩阵)对 canny 蒙版进行卷积。此操作用邻近像素的平均强度值替换像素的强度值。如果一个像素被强度值为 1 的邻近像素包围,则其强度值保持为 1(因为 1/9 乘以 9 等于 1)。但是,位于对象边缘和有问题的区域的像素的强度值会降低。 输出 ![]() 输出 ![]() 输出 ![]() 输出 ![]() 总的来说,当前结果令人满意。尽管仍然存在细胞核聚集在一起的情况,但重要的是我们已经成功识别了原始图像中的所有细胞核。然而,在继续进行并可能过度拟合到特定图像之前,探索 cv2.Canny() 函数中 MinVal 和 MaxVal 参数的不同值,以确定它们在其他图像上的有效性至关重要。这使我们能够建立一种更稳健的方法,这种方法可以很好地推广到各种场景。 输出 ![]() 输出 ![]() 输出 ![]() 输出 ![]() 输出 ![]() 不难看出,在黑色背景和白色前景图像上相同的参数在其他类型的图像上会非常糟糕。 像素分类器我们将尝试构建一个像素分类器,该分类器根据像素及其邻居的灰度值将像素分类为 0 或 255。 输出 ![]() 我们将使用蒙版中找到的细胞核的边界框来定位和分类原始图像中的细胞核。通过考虑组合蒙版中的灰度值和相应的标签,我们将标签分配给边界框内的像素。虽然某些细胞核可能聚集在一起或导致误报,但我们的重点是感兴趣的区域。像素分类器依赖于灰度值和邻近像素信息来做出准确的分类。目标是确保捕获所有具有细胞核的区域,避免漏报,同时允许分类器将 0 值分配给非细胞核区域。像素分类器的性能取决于定义的特征及其准确分类像素的能力。 输出 ![]() 输出 ![]() 当仅考虑边界框内的像素时,类分布似乎偏向 0,这是出乎意料的。这可能是因为边界框包含了比单个细胞核更大的区域。 输出 ![]() 输出 ![]() 像素分类器的性能取决于定义的特征。需要注意的是,我们在同一图像上训练和测试了分类器,这可能导致过度拟合。为了提高性能,我们可以考虑在所有训练图像的边界框内的像素上训练分类器。此外,使用 5x5 窗口并结合诸如像素与细胞核中心之间的距离或 Canny 蒙版内定义窗口中白色像素(255 或 1)的相对密度等特征,可以提高我们的结果。 结论图像处理和机器学习的结合在各个领域开辟了令人兴奋的可能性。通过利用机器学习算法的力量,我们可以从视觉数据中提取有价值的信息,自动化图像分析任务,并增强决策过程。随着研究人员不断创新和完善图像处理中的机器学习技术,我们可以期待进一步的进展,这将改变我们与视觉数据交互和从中获取见解的方式。 下一个主题银行机器学习 |
我们请求您订阅我们的新闻通讯以获取最新更新。