Matlab 减少像素的局部邻域
我最近遇到了一个我似乎无法解决的问题。我有一张经过处理的图像,它包含了许多像素,这些像素以小的“局部”组分布在整个图像上。我希望找到每组的“中心”,并在输出图像中放置一个像素作为每组的代表。分组可以是一个紧密的组,它们之间没有像素零间距,也可以是一个较小的扩展组,它们之间只有几个(小于4~5像素)。我的第一个想法是使用一些沿着形态侵蚀线的东西,但这不能解释稍微分散的像素组的情况。我只是想知道是否有人能给我指出正确的方向。以下是我想做的一个例子: 左侧图像显示输入(大黑点表示一组像素,它们之间没有零),右侧图像是我想要的输出或处理图像类型的示例。最后,我使用MATLAB,可以假设输入图像是一个二值图像(无论黑色是1还是0,逻辑都应该是相同的) 非常感谢你的帮助Matlab 减少像素的局部邻域,matlab,image-processing,computer-vision,Matlab,Image Processing,Computer Vision,我最近遇到了一个我似乎无法解决的问题。我有一张经过处理的图像,它包含了许多像素,这些像素以小的“局部”组分布在整个图像上。我希望找到每组的“中心”,并在输出图像中放置一个像素作为每组的代表。分组可以是一个紧密的组,它们之间没有像素零间距,也可以是一个较小的扩展组,它们之间只有几个(小于4~5像素)。我的第一个想法是使用一些沿着形态侵蚀线的东西,但这不能解释稍微分散的像素组的情况。我只是想知道是否有人能给我指出正确的方向。以下是我想做的一个例子: 左侧图像显示输入(大黑点表示一组像素,它们之间没有
编辑:感谢大家的意见-我将在第二天左右尝试不同的解决方案,我将尝试回复我所做的每个人。非常感谢你们的富有洞察力的投入,非常感谢。在这种情况下,您可以使用区域增长方法,首先连接clstered像素,然后使用腐蚀。如果你知道集群之间的距离比集群本身大的话,那就行了。可能使用重心来确定区域增长后每个斑点的中间。在这种情况下,您可以使用区域增长方法首先连接clstered像素,然后使用腐蚀。如果你知道集群之间的距离比集群本身大的话,那就行了。也许可以使用重心来确定区域生长后每个斑点的中间位置。我推荐一种方法,包括形态学闭合,然后进行连接成分分析。请注意,我已将问题倒置,因此“好点”值较高,“坏背景”值为黑色。这更符合形态学操作的预期定义
path = 'yourimage.png'
space = 5; % you can change this to make it accept bigger spacings
input = imcomplement(rgb2gray(imread(path))) > 0;
input = imclose(input, strel('disk', space));
[labels, num] = bwlabel(input, 8);
output = logical(zeros(size(input)));
for i = 1:num
[r, c] = find(labels==i);
x = round(mean(c))
y = round(mean(r))
output(y,x) = 1;
end
imshow(output)
结果如下所示:
在我看来,这就是你要找的 我推荐一种方法,先进行形态闭合,然后进行连接成分分析。请注意,我已将问题倒置,因此“好点”值较高,“坏背景”值为黑色。这更符合形态学操作的预期定义
path = 'yourimage.png'
space = 5; % you can change this to make it accept bigger spacings
input = imcomplement(rgb2gray(imread(path))) > 0;
input = imclose(input, strel('disk', space));
[labels, num] = bwlabel(input, 8);
output = logical(zeros(size(input)));
for i = 1:num
[r, c] = find(labels==i);
x = round(mean(c))
y = round(mean(r))
output(y,x) = 1;
end
imshow(output)
结果如下所示:
在我看来,这就是你要找的 您描述的问题通常称为。根据您的数据集和分析约束,这可能非常困难。然而,在您的情况下,它很简单,因为您有一个硬阈值(5像素)要使用 Aardvarkk已经提出了一个很好的解决方案,但它并没有真正演示集群的过程。这是一种非常简单的方法,可以对数据进行聚类,得到大致相同的结果
- 如果
已群集,请继续i
- 如果
不在集群中,则创建一个新集群并将i
分配给它i
- 找到靠近
的所有其他点(行i
中等于1的列)i
- 检查这些点是否已在群集中
- 如果是,则将
和i
附近的所有点设置为最小群集idi
- 如果未设置
,且靠近i
的所有点都设置为i
i的
簇
%Generate random points
nPts = 300;
clustId = zeros(nPts,1);
clusterCount = 0;
x = randi(3, [1, nPts])*10+ randn(1, nPts);
y = randi(3, [1, nPts])*10 + randn(1, nPts);
%Compute the distance matrix from http://goo.gl/8mAoC
dist = distance([x;y], [x;y]);
maxDist = 5;
binDist = dist <= maxDist;
for i = 1:nPts
% if this point is already clustered skip it
if clustId(i) ~= 0
continue;
end
%if the current point isn't in a cluster, create a new cluster and add
%the point to that cluster
if clustId(i) == 0
clusterCount = clusterCount+1;
clustId(i) = clusterCount;
fprintf('New point, creating cluster:%d\n', clusterCount);
end
% get the indices of the points that collide with the i
idx = binDist(:,i);
% check to see if idx contains points that already belong to another clustered
% if it doesn't collisionIdx will be equal to i
collisionIdx = idx & clustId>0;
%get the smallest cluster from collisionIdx
mergeClustId = min(clustId(collisionIdx));
%assing all the original points to that cluster
clustId(idx) = mergeClustId;
end
然后将结果绘制为:
figure;
plot(cx,cy,'c.', 'markersize', 50); hold on;
plot(x,y,'.');
您描述的问题通常称为。根据您的数据集和分析约束,这可能非常困难。然而,在您的情况下,它很简单,因为您有一个硬阈值(5像素)要使用 Aardvarkk已经提出了一个很好的解决方案,但它并没有真正演示集群的过程。这是一种非常简单的方法,可以对数据进行聚类,得到大致相同的结果
- 如果
已群集,请继续i
- 如果
不在集群中,则创建一个新集群并将i
分配给它i
- 找到靠近
的所有其他点(行i
中等于1的列)i
- 检查这些点是否已在群集中
- 如果是,则将
和i
附近的所有点设置为最小群集idi
- 如果未设置
,且靠近i
的所有点都设置为i
i的
簇
%Generate random points
nPts = 300;
clustId = zeros(nPts,1);
clusterCount = 0;
x = randi(3, [1, nPts])*10+ randn(1, nPts);
y = randi(3, [1, nPts])*10 + randn(1, nPts);
%Compute the distance matrix from http://goo.gl/8mAoC
dist = distance([x;y], [x;y]);
maxDist = 5;
binDist = dist <= maxDist;
for i = 1:nPts
% if this point is already clustered skip it
if clustId(i) ~= 0
continue;
end
%if the current point isn't in a cluster, create a new cluster and add
%the point to that cluster
if clustId(i) == 0
clusterCount = clusterCount+1;
clustId(i) = clusterCount;
fprintf('New point, creating cluster:%d\n', clusterCount);
end
% get the indices of the points that collide with the i
idx = binDist(:,i);
% check to see if idx contains points that already belong to another clustered
% if it doesn't collisionIdx will be equal to i
collisionIdx = idx & clustId>0;
%get the smallest cluster from collisionIdx
mergeClustId = min(clustId(collisionIdx));
%assing all the original points to that cluster
clustId(idx) = mergeClustId;
end
然后将结果绘制为:
figure;
plot(cx,cy,'c.', 'markersize', 50); hold on;
plot(x,y,'.');
正如斯莱顿所指出的,这是一个集群问题 由于集群的分离非常清楚,因此可以使用简单的基于图形的方法。如果您可以访问图形算法库(例如,存在许多绑定),那么以下方法应该非常简单: