好的,这是加快我认为您正在做的事情的简单方法。 (有更快的方法,但当然它们更复杂一些。)
% 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;
这只是生成一个包含每个红点质心的数组,另一个包含每个黑点质心的数组。然后它使用pdist2计算每个红点和每个黑点之间的距离。
regionprops 还为您提供了边界框,所以我只是手动检查了它以获取红点的直径并硬编码半径。在红点半径范围内的任何黑点都在里面。这是我的测试运行中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)) 进行比较,而只需检查每个黑色质心 (O(m)) 的值。最后,我们使用histc 找出每个红点中有多少个黑点。 (您也可以使用较新的histcounts。)
% 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
结果:
dotCounts =
6
2
4
3
2
1
1
4