【问题标题】:Shortest line between boundary points that passes through the centroid of a shape通过形状质心的边界点之间的最短线
【发布时间】:2017-03-23 02:55:39
【问题描述】:

lesion image

我有一个不规则形状的物体,我必须在其中找到最大和最小直径。

为了找到最大直径,我提取了边界点并找到了所有点之间的距离。在那些给我最大直径的距离中,我选择了最大距离。

boundaries = bwboundaries(binaryImage);
numberOfBoundaries = size(boundaries, 1);
for blobIndex = 1 : numberOfBoundaries
    thisBoundary = boundaries{blobIndex};
    x = thisBoundary(:, 2); % x = columns.
    y = thisBoundary(:, 1); % y = rows.

    % Find which two boundary points are farthest from each other.
    maxDistance = -inf;
    for k = 1 : length(x)
        distances = sqrt( (x(k) - x) .^ 2 + (y(k) - y) .^ 2 );
        [thisMaxDistance, indexOfMaxDistance] = max(distances);
        if thisMaxDistance > maxDistance
            maxDistance = thisMaxDistance;
            index1 = k;
            index2 = indexOfMaxDistance;
        end
    end

我附上了包含最长直径的图片。

我还需要一条穿过质心的线段,连接长度最短的两个边界点。当我尝试通过修改上述代码来找到最短直径时,找到min(distances),我收到一条错误消息:

使用griddedInterpolant 时出错 输入点的坐标必须是有限值;不允许使用 InfNaN

我需要怎么做才能找到这个物体的最短“直径”(即通过质心)?

【问题讨论】:

  • 哪一行给你这个错误?
  • 当我取最小(距离)时,我得到了零。这可能就是我收到错误的原因。我找到最短直径的逻辑对吗?
  • 当您将max 更改为min 时,您会寻找距离最近的两个边界点。显然,这将是边界的任何点及其本身,距离为零。
  • 如果您发布在代码开头使用的binaryImage,我可能会提供帮助。
  • 我已经编辑了我的问题并附上了图片。请指导。

标签: matlab geometry line shape min


【解决方案1】:

可以像这样使用极坐标图像:

lesion = imread('lesion.jpg');
bw = lesion > 100;
c = regionprops(bw,'Centroid');
c = c.Centroid;
% polar args
t = linspace(0,2*pi,361);
t(end) = [];
r = 0:ceil(sqrt(numel(bw)/4));
[tg,rg] = meshgrid(t,r);
[xg,yg] = pol2cart(tg,rg);
xoff = xg + c(1);
yoff = yg + c(2);
% polar image
pbw = interp2(double(bw),xoff,yoff,'nearest') == 1;
[~,radlen] = min(pbw,[],1);
radlen(radlen == 1) = max(r);
n = numel(radlen);
% add two edges of line to form diameter
diamlen = radlen(1:n/2) + radlen(n/2+1:n);
% find min diameter
[mindiam,tminidx1] = min(diamlen);
tmin = t(tminidx1);
rmin = radlen(tminidx1);
tminidx2 = tminidx1 + n/2;
xx = [xoff(radlen(tminidx1),tminidx1) xoff(radlen(tminidx2),tminidx2)];
yy = [yoff(radlen(tminidx1),tminidx1) yoff(radlen(tminidx2),tminidx2)];
% viz
figure;
subplot(121);
imshow(pbw);
title('polar image');
subplot(122);
imshow(bw);
hold on
plot(c(1),c(2),'or')
plot(xx,yy,'g')
legend('centroid','shortest diameter');

输出是:

【讨论】:

  • 这很完美!太感谢了!但是在 bw>100 时,100 是固定值吗?这是什么意思?
  • bw = lesion > 100 只是我为这个例子创建二进制病变图像的方法。它与建议的算法无关,您可以删除此行并使用自己的图像。
  • 我对您使用的代码有疑问。 radlen(radlen==1)=max(r) 到底是什么意思?
  • 另外,最初将其转换为极坐标形式有何帮助?我试图理解你在这里使用的算法。你能解释一下你是如何找到最短直径的吗? '@user2999345'
  • 它确保发现最小 (=1) 而实际上不是的半径长度设置为最大。实际上正确的做法是:[binaryVal,radlen] = min(pbw,[],1); 然后radlen(binaryVal == 1) = max(r);
猜你喜欢
  • 2019-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 2020-03-28
相关资源
最近更新 更多