如何在matlab中找到旋转对象的角点?

时间:2017-05-30 16:52:21

标签: matlab image-processing corner-detection

我想找到物体的角落。 我尝试了以下代码:

Vstats = regionprops(BW2,'Centroid','MajorAxisLength','MinorAxisLength',...
    'Orientation');
u = [Vstats.Centroid];
VcX = u(1:2:end);
VcY = u(2:2:end);

[VcY id] = sort(VcY); % sorting regions by vertical position
VcX = VcX(id);
Vstats = Vstats(id); % permute according sort
Bv = Bv(id);

Vori = [Vstats.Orientation];
VRmaj = [Vstats.MajorAxisLength]/2;
VRmin = [Vstats.MinorAxisLength]/2;

% find corners of vertebrae
figure,imshow(BW2)
hold on
% C = corner(VER);
% plot(C(:,1), C(:,2), 'or');

C = cell(size(Bv));
Anterior = zeros(2*length(C),2);
Posterior = zeros(2*length(C),2);
for i = 1:length(C) % for each region
    cx = VcX(i); % centroid coordinates
    cy = VcY(i);
    bx = Bv{i}(:,2); % edge points coordinates
    by = Bv{i}(:,1);
    ux = bx-cx; % move to the origin
    uy = by-cy;
    [t, r] = cart2pol(ux,uy); % translate in polar coodinates
    t = t - deg2rad(Vori(i)); % unrotate
    for k = 1:4 % find corners (look each quadrant)
        fi = t( (t>=(k-3)*pi/2) & (t<=(k-2)*pi/2) );
        ri = r( (t>=(k-3)*pi/2) & (t<=(k-2)*pi/2) );
        [rp, ip] = max(ri); % find farthest point       
        tc(k) = fi(ip); % save coordinates
        rc(k) = rp;
    end
    [xc,yc] = pol2cart(tc+1*deg2rad(Vori(i)) ,rc); % de-rotate, translate in cartesian 
    C{i}(:,1) = xc + cx; % return to previous place
    C{i}(:,2) = yc + cy;
    plot(C{i}([1,4],1),C{i}([1,4],2),'or',C{i}([2,3],1),C{i}([2,3],2),'og')

    % save coordinates :
    Anterior([2*i-1,2*i],:) = [C{i}([1,4],1), C{i}([1,4],2)];
    Posterior([2*i-1,2*i],:) = [C{i}([2,3],1), C{i}([2,3],2)];
end

我的输入图片是: enter image description here

我得到了以下输出图像 enter image description here

未正确检测到图像中最下面的对象。我该如何更正代码?它无法用于旋转图像。

2 个答案:

答案 0 :(得分:0)

您可以从图像中获取所有点,并使用 kmeans 聚类并将点分为8组。分区完成后,你就可以获得积分,你可以选择你想要的积分。

    rgbImage = imread('your image') ; 
    %% crop out the unwanted white background from the image
    grayImage = min(rgbImage, [], 3);
    binaryImage = grayImage < 200;
    binaryImage = bwareafilt(binaryImage, 1);
    [rows, columns] = find(binaryImage);
    row1 = min(rows);
    row2 = max(rows);
    col1 = min(columns);
    col2 = max(columns);
    % Crop
    croppedImage = rgbImage(row1:row2, col1:col2, :);
    I = rgb2gray(croppedImage) ;
    %% Get the white regions 
    [y,x,val] = find(I) ;
    %5 use kmeans clustering 
    [idx,C] = kmeans([x,y],8) ;
    %%
    figure
   imshow(I) ;
hold on
for i = 1:8
    xi = x(idx==i) ; yi = y(idx==i) ;
    id1=convhull(xi,yi) ;
    coor = [xi(id1) yi(id1)] ;
    [id,c] = kmeans(coor,4) ;    

    plot(coor(:,1),coor(:,2),'r','linewidth',3) ;
    plot(c(:,1),c(:,2),'*b')
end

enter image description here

enter image description here

现在我们能够捕获区域......边界/凸包船体点在手。你可以用积分做你想要的数学。

答案 1 :(得分:-2)

你解决了这个问题吗?我看着它,似乎是由地区支持者提供的轮换。好像都没了。为了解决这个问题,我已经准备好了一个快速解决方案:我已经扩大了图像以缩小间隙,找到了每个脊柱的4个最远的峰值,然后验证了峰值是在左侧还是在右侧中心线(我通过外推形式排序的质心获得)。这种方法似乎适用于这个特殊问题。

BW2 = rgb2gray(Image);
BW2 = imbinarize(BW2);

%dilate and erode will help to remove extra features of the vertebra
se = strel('disk',4,4);
BW2_dilate = imdilate(BW2,se);
BW2_erode = imerode(BW2_dilate,se);

sb = bwboundaries(BW2_erode);

figure
imshow(BW2)
hold on

centerLine = [];
corners = [];

for bone = 1:length(sb)

    x0 = sb{bone}(:,2) - mean(sb{bone}(:,2));
    y0 = sb{bone}(:,1) - mean(sb{bone}(:,1));

    %save the position of the centroid
    centerLine = [centerLine; [mean(sb{bone}(:,1)) mean(sb{bone}(:,2))]];

    [th0,rho0] = cart2pol(x0,y0);

    %make sure that the indexing starts at the dip, not at the corner
    lowest_val = find(rho0==min(rho0));

    rho1 = [rho0(lowest_val:end); rho0(1:lowest_val-1)];
    th00 = [th0(lowest_val:end); th0(1:lowest_val-1)];
    y1 = [y0(lowest_val:end); y0(1:lowest_val-1)];
    x1 = [x0(lowest_val:end); x0(1:lowest_val-1)];

    %detect corners, using smooth data to remove noise
    [pks,locs] = findpeaks(smooth(rho1));
    [pksS,idS] = sort(pks,'descend');

    %4 most pronounced peaks are where the corners are
    edgesFndCx = x1(locs(idS(1:4)));
    edgesFndCy = y1(locs(idS(1:4)));

    edgesFndCx = edgesFndCx + mean(sb{bone}(:,2));
    edgesFndCy = edgesFndCy + mean(sb{bone}(:,1));

    corners{bone} = [edgesFndCy edgesFndCx];
end

[~,idCL] = sort(centerLine(:,1),'descend');
centerLine = centerLine(idCL,:);

%extrapolate the spine centerline
yDatExt= 1:size(BW2_erode,1);
extrpLine = interp1(centerLine(:,1),centerLine(:,2),yDatExt,'spline','extrap');

plot(centerLine(:,2),centerLine(:,1),'r')
plot(extrpLine,yDatExt,'r')

%find edges to the left, and to the right of the centerline
for bone = 1:length(corners)    
    x0 = corners{bone}(:,2);
    y0 = corners{bone}(:,1);
    for crn = 1:4 
        xCompare = extrpLine(y0(crn));
        if x0(crn) < xCompare
            plot(x0(crn),y0(crn),'go','LineWidth',2)
        else
            plot(x0(crn),y0(crn),'ro','LineWidth',2)
        end
    end  
end

Solution