我有两个单独的图像,它们都来自同一个起始图像。我想基本上叠加这两个并计算一个图像中有多少个圆落在第二个图像中的每个较大的圆圈内:这里有一些我正在谈论的图像:
理想情况下,我可以跟踪每个较大的圆圈,并使用较小的嵌套圆圈对其进行标记。到目前为止,我已尝试使用较大圆圈的半径,并逐个循环检查基于坐标的所有内容。
这似乎非常昂贵,我想知道是否有更好的方法来实现它。
答案 0 :(得分:0)
好的,这是加速我认为你正在做的事情的简单方法。 (有更快的方法,但当然它们有点复杂。)
foo
这只生成一个包含每个红点的质心的数组,另一个包含每个黑点的质心。然后使用pdist2
计算每个红点和每个黑点之间的距离。
regionprops
也为你提供了边界框,所以我只是手动检查它以获得红点的直径并硬编码半径。红点内半径范围内的任何黑点都在里面。以下是我的测试运行中% Get the statistics for redDots.jpg
img = imread('redDots.jpg'); % You should really use a lossless image format like .png
gimg = rgb2gray(img); % Convert to grayscale
bwimg = im2bw(gimg, .5); % Convert to bw image (guessing at the threshold)
bwimg = ~bwimg; % Invert the bw image so dots are white
stats = regionprops(bwimg); % Find statistics of dots (centroid, area, bounding box)
redCentroids = reshape([stats(:).Centroid], 2, []).'; % Put centroids in format for pdist2
% Repeat the same basic procedure for blackDots.jpg
img2 = imread('blackDots.jpg');
bwimg2 = im2bw(img2, .5); % blackDots.jpg is alread bw image
bwimg2 = ~bwimg2;
stats2 = regionprops(bwimg2);
blackCentroids = reshape([stats2(:).Centroid], 2, []).';
distMatrix = pdist2(redCentroids, blackCentroids);
radius = 38; % found from stats.BoundingBox
connectedDots = distMatrix < radius;
的值:
connectedDots
在connectedDots =
1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1
矩阵中,每一行代表一个红点。每列代表一个黑点。因此,对于每一行,对应于该行的红点内的每个黑点都有connectedDots
。 (如果您想知道哪一个,您可以返回1
结构并查看stats
。)
要查找每个红点中的黑点数,请执行以下操作:
stats(rownumber).Centroid
替代方法
此方法通过将带有红点的图像转换为带标签的图像来避免>> sum(connectedDots,2)
ans =
6
2
4
3
2
1
1
4
。然后,当我们找到黑点的质心坐标时,我们只需检查标记图像上的那些坐标(实际上是指数),看看那里有什么。这样,我们只需要检查每个黑色质心(pdist2
)的值,而不是将每个红色质心与每个黑色质心(O(n*m)
)进行比较。最后,我们使用histc
找出每个红点中有多少个黑点。 (您也可以使用较新的histcounts。)
O(m)
结果:
% Process the black dot image the same way as before
imgB = imread('blackDots.jpg');
bwimgB = im2bw(imgB, .5);
bwimgB = ~bwimgB;
statsB = regionprops(bwimgB);
% This time round to get integer subscripts
blackCentroids = round(reshape([statsB(:).Centroid], 2, []).');
% Get the corresponding indices...
% Centroids are in (x,y) order instead of (row,col)
centroidIdx = sub2ind(size(imgB), blackCentroids(:,2), blackCentroids(:,1));
% Convert red dot image to bwimg as before
img = imread('redDots.jpg');
gimg = rgb2gray(img);
bwimg = im2bw(gimg, .5);
bwimg = ~bwimg;
% Instead of getting centroids, convert to labeled image
redLabelImage = bwlabel(bwimg); % Label the connected components (red dots)
dotLocations = redLabelImage(centroidIdx); % Get the label at each index
dotCounts = histc(dotLocations, 1:max(redLabelImage(:))) % Count them up