霍夫变换分割后如何去除重叠的圆圈
How can i remove overlaping circles after Hough Transform segmentation
我从事图像分割工作,测试了很多不同的分割算法,以便进行比较研究。目前我正在使用 Hough 变换在图像中查找圆圈。我使用的图像有很多对象,所以当 Í 计算对象时,结果是 hudge。我认为问题在于重叠的圆圈。你知道我怎样才能删除重叠的圆圈以获得更接近现实的结果吗?
我使用的代码是:
clear all, clc;
% Image Reading
I=imread('0001_c3.png');
figure(1), imshow(I);set(1,'Name','Original')
% Gaussian Filter
W = fspecial('gaussian',[10,10]);
J = imfilter(I,W);
figure(2);imshow(J);set(2,'Name','Filtrada média');
X = rgb2gray(J);
figure(3);imshow(X);set(3,'Name','Grey');
% Finding Circular objects -- Houng Transform
[centers, radii, metric] = imfindcircles(X,[10 20], 'Sensitivity',0.92,'Edge',0.03); % [parasites][5 30]
centersStrong = centers(1:60,:); % number of objects
radiiStrong = radii(1:60);
metricStrong = metric(1:60);
viscircles(centersStrong, radiiStrong,'EdgeColor','r');
length(centers)% result=404!
您可以简单地遍历圆圈并检查其他人是否 "close"。如果是这样,请忽略它们。
idx_mask = ones(size(radii));
min_dist = 1; % relative value. Tweak this if slight overlap is OK.
for i = 2:length(radii)
cur_cent = centers(i, :);
for j = 1:i-1
other_cent = centers(j,:);
x_dist = other_cent(1) - cur_cent(1);
y_dist = other_cent(2) - cur_cent(2);
if sqrt(x_dist^2+y_dist^2) < min_dist*(radii(i) + radii(j)) && idx_mask(j) == 1
idx_mask(i) = 0;
break
end
end
end
%%
idx_mask = logical(idx_mask);
centers_use = centers(idx_mask, :);
radii_use = radii(idx_mask, :);
metric_use = metric(idx_mask, :);
viscircles(centers_use, radii_use,'EdgeColor','b');
图中所有圆圈为红色,过滤后的圆圈为蓝色。
if
子句检查两件事:
- 圆心是否比它们的半径之和更近?
- 另一个圈子是否仍在考虑的圈子列表中?
如果两个问题的答案都是肯定的,那么忽略 "current circle".
循环的设置方式,它将保留 higher up
的圆圈(具有较低的行索引)。照原样,圆圈已经按 metric
降序排列。换句话说,正如这段代码将保持更高的圈子 metric
.
可以优化代码,使循环 运行 更快,但我认为单张图片中不会有数百万个圆圈。我尝试以一种更易于人类阅读的方式编写它。
我从事图像分割工作,测试了很多不同的分割算法,以便进行比较研究。目前我正在使用 Hough 变换在图像中查找圆圈。我使用的图像有很多对象,所以当 Í 计算对象时,结果是 hudge。我认为问题在于重叠的圆圈。你知道我怎样才能删除重叠的圆圈以获得更接近现实的结果吗?
我使用的代码是:
clear all, clc;
% Image Reading
I=imread('0001_c3.png');
figure(1), imshow(I);set(1,'Name','Original')
% Gaussian Filter
W = fspecial('gaussian',[10,10]);
J = imfilter(I,W);
figure(2);imshow(J);set(2,'Name','Filtrada média');
X = rgb2gray(J);
figure(3);imshow(X);set(3,'Name','Grey');
% Finding Circular objects -- Houng Transform
[centers, radii, metric] = imfindcircles(X,[10 20], 'Sensitivity',0.92,'Edge',0.03); % [parasites][5 30]
centersStrong = centers(1:60,:); % number of objects
radiiStrong = radii(1:60);
metricStrong = metric(1:60);
viscircles(centersStrong, radiiStrong,'EdgeColor','r');
length(centers)% result=404!
您可以简单地遍历圆圈并检查其他人是否 "close"。如果是这样,请忽略它们。
idx_mask = ones(size(radii));
min_dist = 1; % relative value. Tweak this if slight overlap is OK.
for i = 2:length(radii)
cur_cent = centers(i, :);
for j = 1:i-1
other_cent = centers(j,:);
x_dist = other_cent(1) - cur_cent(1);
y_dist = other_cent(2) - cur_cent(2);
if sqrt(x_dist^2+y_dist^2) < min_dist*(radii(i) + radii(j)) && idx_mask(j) == 1
idx_mask(i) = 0;
break
end
end
end
%%
idx_mask = logical(idx_mask);
centers_use = centers(idx_mask, :);
radii_use = radii(idx_mask, :);
metric_use = metric(idx_mask, :);
viscircles(centers_use, radii_use,'EdgeColor','b');
图中所有圆圈为红色,过滤后的圆圈为蓝色。
if
子句检查两件事:
- 圆心是否比它们的半径之和更近?
- 另一个圈子是否仍在考虑的圈子列表中?
如果两个问题的答案都是肯定的,那么忽略 "current circle".
循环的设置方式,它将保留 higher up
的圆圈(具有较低的行索引)。照原样,圆圈已经按 metric
降序排列。换句话说,正如这段代码将保持更高的圈子 metric
.
可以优化代码,使循环 运行 更快,但我认为单张图片中不会有数百万个圆圈。我尝试以一种更易于人类阅读的方式编写它。