Computing object statistics from the second central moments

前端 未结 2 1194
你的背包
你的背包 2020-12-18 05:08

I\'m currently working on writing a version of the MATLAB RegionProps function for GNU Octave. I have most of it implemented, but I\'m still struggling with the implementat

相关标签:
2条回答
  • 2020-12-18 05:43

    EDIT:

    According to Wikipedia:

    the eignevalues [...] are proportional to the squared length of the eigenvector axes.

    which is explained by:

    axisLength = 4 * sqrt(eigenValue)
    

    Shown below is my version of the code (I vectorized the moments functions):

    my_regionprops.m

    function props = my_regionprops(im)
        cm00 = central_moments(im, 0, 0);
        up20 = central_moments(im, 2, 0) / cm00;
        up02 = central_moments(im, 0, 2) / cm00;
        up11 = central_moments(im, 1, 1) / cm00;
    
        covMat = [up20 up11 ; up11 up02];
        [V,D] = eig( covMat );
        [D,order] = sort(diag(D), 'descend');        %# sort cols high to low
        V = V(:,order);
    
        %# D(1) = (up20+up02)/2 + sqrt(4*up11^2 + (up20-up02)^2)/2;
        %# D(2) = (up20+up02)/2 - sqrt(4*up11^2 + (up20-up02)^2)/2;
    
        props = struct();
        props.MajorAxisLength = 4*sqrt(D(1));
        props.MinorAxisLength = 4*sqrt(D(2));
        props.Eccentricity = sqrt(1 - D(2)/D(1));
        %# props.Orientation = -atan(V(2,1)/V(1,1)) * (180/pi);      %# sign?
        props.Orientation = -atan(2*up11/(up20-up02))/2 * (180/pi);
    end
    
    function cmom = central_moments(im,i,j)
        rawm00 = raw_moments(im,0,0);
        centroids = [raw_moments(im,1,0)/rawm00 , raw_moments(im,0,1)/rawm00];
        cmom = sum(sum( (([1:size(im,1)]-centroids(2))'.^j * ...
                         ([1:size(im,2)]-centroids(1)).^i) .* im ));
    end
    
    function outmom = raw_moments(im,i,j)
        outmom = sum(sum( ((1:size(im,1))'.^j * (1:size(im,2)).^i) .* im ));
    end
    

    ... and the code to test it:

    test.m

    I = imread('135deg100by30ell.png');
    I = logical(I);
    
    >> p = regionprops(I, {'Eccentricity' 'MajorAxisLength' 'MinorAxisLength' 'Orientation'})
    p = 
        MajorAxisLength: 101.34
        MinorAxisLength: 32.296
           Eccentricity: 0.94785
            Orientation: -44.948
    
    >> props = my_regionprops(I)
    props = 
        MajorAxisLength: 101.33
        MinorAxisLength: 32.275
           Eccentricity: 0.94792
            Orientation: -44.948
    
    %# these values are by hand only ;)
    subplot(121), imshow(I), imdistline(gca, [17 88],[9 82]);
    subplot(122), imshow(I), imdistline(gca, [43 67],[59 37]);
    

    screenshot

    0 讨论(0)
  • 2020-12-18 05:53

    Are you sure about the core of your raw_moments function? You might try

    amount = ((x-1) ** i) * ((y-1) ** j) * im(y,x);
    

    This doesn't seem like enough to cause the problems you're seeing, but it might be at least a part.

    0 讨论(0)
提交回复
热议问题