how to average the close points ?
8 次查看(过去 30 天)
显示 更早的评论
hi all, I have a 1200*2 matrix let's call it 'center', which means different points in a photo. while several points are very close, for example, center(10,:)=[120,200]; and center(13,:)=[122,200]; or center(110,:)=[1420,2400]; and center(113,:)=[1420,2402] etc. I want to find get a new matrix only with the average value of close points. which means the points center(10,:) and center(13,:) could be presented as a new element[121,200], so as other points. Is there any efficient way to to this? thanks a lot.
0 个评论
回答(2 个)
Walter Roberson
2015-6-17
No, you cannot do this because "close" is not transitive.
If point A is close to point B, and point B is close to point C, then point A might not be close to point C. If you happened to be looking at point A then you would average A and B but leave C out because it was too far, but if you were looking at point B then you would average A, B, and C because both A and C are close to B. The result is thus going to depend upon the order of processing, and clearly that is not what you would want.
In order to do this you would need to determine through some other means which coordinates (does not need to be an existing point) that are to be the "nucleus" to gather together close points.
You are implicitly asking to do clustering, with all the difficulties that implies.
Alfonso Nieto-Castanon
2015-6-18
编辑:Alfonso Nieto-Castanon
2015-6-18
If you do not have "lines" of close points (the transitiveness issue that Walter mentioned), a simple and quick way to do this could be (here X is your 1200x2 matrix of point coordinates):
mindist = 5; % desired minimum distance between two points
nX = sum(X.^2,2);
d = bsxfun(@plus,nX,nX')-2*X*X';
[p,~,r] = dmperm(d<mindist^2);
nvoxels = diff(r);
for n=find(nvoxels>1)
idx = p(r(n):r(n+1)-1);
X(idx,:) = repmat(mean(X(idx,:),1),numel(idx),1);
X(idx(2:end),:) = nan;
end
X(any(isnan(X),2),:) = [];
If you do have "lines" of close points, and you do not want them collapsed into a single point, then yes, you would need some sort of clustering algorithm. If nothing more sophisticated is available (e.g. using the Statistics toolbox) you could try something like the following:
mindist = 5; % desired minimum distance between two points
while 1
nX = sum(X.^2,2);
d = bsxfun(@plus,nX,nX')-2*X*X';
[i,j] = find(d<mindist^2);
idx = find(i~=j,1);
if isempty(idx), break; end
X(i(idx),:) = mean(X([i(idx),j(idx)],:),1);
X(j(idx),:) = [];
end
4 个评论
Walter Roberson
2015-6-18
Take 3 equidistant points of distance R apart, an equilateral triangle. Draw circles of radius R around each of them. The area that is shared by all three is the area where any extra points would not be further than R away from any of the three points. I do not have the formula for the area of overlap at the moment, but it amounts to about 0.224 * Pi * R^2. The feasible area falls quickly.
Alfonso Nieto-Castanon
2015-6-18
编辑:Alfonso Nieto-Castanon
2015-6-18
I believe I understand your point, but I am not claiming that the graph approach is a suitable substitute for clustering, I am simply saying than in some simple cases your distribution of point-to-point distances has some clearly discernable "small-distance" outliers and for those cases only you can use this simpler approach to combine those abnormally-close points. For example, in my experience, I have run into these cases when I use a general-mixture model to fit some data (and I get multiple centroids that are effectively defining the same cluster so I would like to combine those), or when I run a filter-bank to find interesting features in an image (where again I often get small clusters of suprathreshold feature detectors effectively pointing at the same feature), and in many other scenarios, so I can assure you that these cases do exist, no matter how unlikely they would seem if your points followed a normal or poisson distribution :)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!