计算标记图像中的对象数量
Counting Number of objects in labeled image
我有一张图像,我试图计算对象的数量——主要是实心圆圈——所以为了消除圆圈之间的重叠,我最终得到了一张标记图像,到目前为止效果很好,不,我申请了
bwconncomp(theLabeledImage,4);
以获取实心圆圈数的方式,但我得到的看起来像这样
Connectivity: 4
ImageSize: [505 394 3]
NumObjects: 87
PixelIdxList: {1x87 cell}
这恰好是错误的,给定的输出是 87,而我在图像中有 48。
图片:
所以有什么建议 :) ?.
这里有几件事让你绊倒了。
首先,我认为您是 运行 bwconncomp 在标记图像上,而不是二值图像上。这将重复计算很多区域,因为您最终会计算区域及其边界。请参阅下面我执行此操作的代码 (labelImageBWCC = bwconncomp(rgb,4);
),最终得到 89 个区域的计数。
其次,分水岭变换有时不会在交界处彻底中断,而是最终会在边界上生成一堆小区域。这是带有分水岭变换的 'plateau problem',但值得庆幸的是,我们可以通过简单地过滤掉具有面积阈值的那些小区域来避免这个问题的后果。
纠正这些问题后,您可以获得正确数量的硬币。代码在这里:
img = imread('coins.tif');
% Threshold and binarize image and fill holes
binImg = ~im2bw(img, graythresh(img));
binImg = imfill(binImg, 'holes');
% Distance transform and watershed segmentation
D = bwdist(~binImg);
D = -D;
D(~binImg) = -Inf;
L = watershed(D);
% Generate label image
rgb = label2rgb(L,'jet',[.5 .5 .5]);
% Show results of watershed
figure, imshow(rgb,'InitialMagnification','fit')
title('Watershed transform of coins.tif')
% Count number of label regions. Note - this is incorrect! This will
% count borders and background, which we don't want
labelImageBWCC = bwconncomp(rgb,4);
% Generate new binary image that only looks at individual regions generated
% by watershed segmentation so we are counting watershed regions, not label
% colors
binWatershed = L > 1; % 1 is background region; any region with index > 1 is coin
minCoinSize = 50; % minimum size in pixels
regs = regionprops(binWatershed, 'Area', 'Centroid', 'PixelIdxList');
% Remove all regions with size below threshold
regs(vertcat(regs.Area) < minCoinSize) = [];
% Display image with coin count labeled
figure, imshow(img)
hold on
for k = 1:numel(regs)
text(regs(k).Centroid(1), regs(k).Centroid(2), num2str(k), ...
'Color', 'r', 'HorizontalAlignment', 'center')
end
hold off
我有一张图像,我试图计算对象的数量——主要是实心圆圈——所以为了消除圆圈之间的重叠,我最终得到了一张标记图像,到目前为止效果很好,不,我申请了
bwconncomp(theLabeledImage,4);
以获取实心圆圈数的方式,但我得到的看起来像这样
Connectivity: 4
ImageSize: [505 394 3]
NumObjects: 87
PixelIdxList: {1x87 cell}
这恰好是错误的,给定的输出是 87,而我在图像中有 48。
图片:
所以有什么建议 :) ?.
这里有几件事让你绊倒了。
首先,我认为您是 运行 bwconncomp 在标记图像上,而不是二值图像上。这将重复计算很多区域,因为您最终会计算区域及其边界。请参阅下面我执行此操作的代码 (labelImageBWCC = bwconncomp(rgb,4);
),最终得到 89 个区域的计数。
其次,分水岭变换有时不会在交界处彻底中断,而是最终会在边界上生成一堆小区域。这是带有分水岭变换的 'plateau problem',但值得庆幸的是,我们可以通过简单地过滤掉具有面积阈值的那些小区域来避免这个问题的后果。
纠正这些问题后,您可以获得正确数量的硬币。代码在这里:
img = imread('coins.tif');
% Threshold and binarize image and fill holes
binImg = ~im2bw(img, graythresh(img));
binImg = imfill(binImg, 'holes');
% Distance transform and watershed segmentation
D = bwdist(~binImg);
D = -D;
D(~binImg) = -Inf;
L = watershed(D);
% Generate label image
rgb = label2rgb(L,'jet',[.5 .5 .5]);
% Show results of watershed
figure, imshow(rgb,'InitialMagnification','fit')
title('Watershed transform of coins.tif')
% Count number of label regions. Note - this is incorrect! This will
% count borders and background, which we don't want
labelImageBWCC = bwconncomp(rgb,4);
% Generate new binary image that only looks at individual regions generated
% by watershed segmentation so we are counting watershed regions, not label
% colors
binWatershed = L > 1; % 1 is background region; any region with index > 1 is coin
minCoinSize = 50; % minimum size in pixels
regs = regionprops(binWatershed, 'Area', 'Centroid', 'PixelIdxList');
% Remove all regions with size below threshold
regs(vertcat(regs.Area) < minCoinSize) = [];
% Display image with coin count labeled
figure, imshow(img)
hold on
for k = 1:numel(regs)
text(regs(k).Centroid(1), regs(k).Centroid(2), num2str(k), ...
'Color', 'r', 'HorizontalAlignment', 'center')
end
hold off