Main Content

本页对应的英文页面已更新,但尚未翻译。 若要查看最新内容,请点击此处访问英文页面。

校正亮度不均匀问题并分析前景对象

此示例说明如何在分析前的预处理步骤增强图像。在此示例中,您可以校正背景亮度不均匀问题,并将图像转换为二值图像,以便于识别前景对象(单个米粒)。然后,您可以分析对象,例如计算每粒大米的面积,并可以计算图像中所有对象的统计量。

预处理图像

将图像读入工作区。

I = imread('rice.png');
imshow(I)

图像中心的背景亮度比底部亮度高。预处理图像,使背景亮度更加均匀。

第一步,使用形态学开运算删除所有前景(米粒)。开运算会删除无法完全包含结构元素的小对象。定义半径为 15 的盘形结构元素,它完全可放入一粒米内。

se = strel('disk',15)
se = 
strel is a disk shaped structuring element with properties:

      Neighborhood: [29x29 logical]
    Dimensionality: 2

要执行形态学开运算,请使用具有结构元素的 imopen

background = imopen(I,se);
imshow(background)

从原始图像 I 中减去背景逼近图像 background,然后查看生成的图像。从原始图像中减去调整后的背景图像后,生成的图像具有均匀的背景,但现在对于分析来说有点暗。

I2 = I - background;
imshow(I2)

使用 imadjust,通过在低强度和高强度下都对 1% 的数据进行饱和处理,并通过拉伸强度值以填充 uint8 动态范围,来提高处理后的图像 I2 的对比度。

I3 = imadjust(I2);
imshow(I3)

请注意,前面的两个步骤可以由使用 imtophat 的一个步骤来代替完成,后者先计算形态学开运算,然后从原始图像中减去它。

I2 = imtophat(I,strel('disk',15));

创建处理后的图像的二值版本,以便使用工具箱函数进行分析。使用 imbinarize 函数将灰度图像转换为二值图像。使用 bwareaopen 函数去除图像中的背景噪声。

bw = imbinarize(I3);
bw = bwareaopen(bw,50);
imshow(bw)

识别图像中的对象

现在您已创建原始图像的二值版本,您可以对图像中的对象执行分析。

在二值图像中查找所有连通分量(对象)。结果的准确度取决于对象的大小、连通性参数(4、8 或任意值),以及是否有相互接触的对象(在这种情况下,它们可能被标记为一个对象)。二值图像 bw 中的一些米粒相互接触。

cc = bwconncomp(bw,4)
cc = struct with fields:
    Connectivity: 4
       ImageSize: [256 256]
      NumObjects: 95
    PixelIdxList: {1x95 cell}

cc.NumObjects
ans = 95

查看图像中标记为 50 的米粒。

grain = false(size(bw));
grain(cc.PixelIdxList{50}) = true;
imshow(grain)

通过创建标签矩阵,然后将其显示为伪彩色索引图像,可视化图像中的所有连通分量。

使用 labelmatrix 根据 bwconncomp 的输出创建标签矩阵。请注意,labelmatrix 将标签矩阵存储在依对象数量得出的最小数值类中。

labeled = labelmatrix(cc);
whos labeled
  Name           Size             Bytes  Class    Attributes

  labeled      256x256            65536  uint8              

使用 label2rgb 选择颜色图、背景颜色以及标签矩阵中的对象如何映射到颜色图中的颜色。在伪彩色图像中,用于标识标签矩阵中每个对象的标签映射到相关联的颜色图矩阵中的不同颜色。

RGB_label = label2rgb(labeled,'spring','c','shuffle');
imshow(RGB_label)

计算基于面积的统计量

使用 regionprops 计算图像中每个对象的面积。每个米粒均为 cc 结构体中的一个连通分量。

graindata = regionprops(cc,'basic')
graindata=95×1 struct array with fields:
    Area
    Centroid
    BoundingBox

创建新向量 grain_areas,它保存每个米粒的面积测量值。

grain_areas = [graindata.Area];

计算第 50 个分量的面积。

grain_areas(50)
ans = 194

找到并显示面积最小的米粒。

[min_area, idx] = min(grain_areas)
min_area = 61
idx = 16
grain = false(size(bw));
grain(cc.PixelIdxList{idx}) = true;
imshow(grain)

使用 histogram 命令创建米粒面积的直方图。

histogram(grain_areas)
title('Histogram of Rice Grain Area')

另请参阅

| | | | | | | | |