Implementing ridge detection

后端 未结 3 1712
说谎
说谎 2021-02-06 08:23

I\'m trying to write a ridge detection algorithm, and all of the sources I\'ve found seem to conflate edge detection with ridge detection. Right now, I\'ve implemented the Canny

相关标签:
3条回答
  • 2021-02-06 09:03

    If anyone is still interested in this, here is an implementation of the ridges/valleys algorithm: C++ source code. Look for a function called get_ridges_or_valleys(). This implementation is a 3D version of the algorithm proposed by Linderhed (2009). See page 8 of the paper for the ridges/valleys algorithm.

    0 讨论(0)
  • 2021-02-06 09:04

    I was going to suggest cleaning up your lines like Ian said, but if you don't want to do that, you might also look into doing some variant of a hough transform.

    http://en.wikipedia.org/wiki/Hough_transform

    You should be able to get the actual equation for the line from this, so you can make it as thin or as thick as you like. The only tricky part is figuring out where the line ends.

    Here's the code I wrote for a hough transform a few years ago, written in MATLAB. I'm not sure how well it works anymore, but it should give you a general idea. It will find all the lines (not segments) in an image

    im = imread('cube.tif');
    [bin1,bin2,bin3] = canny(im);
    
    %% define constants
    binary = bin1;
    distStep = 10; % in pixels
    angStep = 6; % in degrees
    thresh = 50;
    
    %% vote
    maxDist = sqrt((size(binary,1))^2+(size(binary,2))^2);
    angLoop = 0:angStep*pi/180:pi;
    origin = size(binary)/2;
    accum = zeros(ceil(maxDist/distStep)+1,ceil(360/angStep)+1);
    
    for y=1:size(binary,2)
        for x=1:size(binary,1)
        if binary(x,y)
            for t = angLoop
            dx = x-origin(1);
            dy = y-origin(2);
            r = x*cos(t)+y*sin(t);
            if r < 0
                r = -r;
                t = t + pi;
            end
            ri = round(r/distStep)+1;
            ti = round(t*180/pi/angStep)+1;
            accum(ri,ti) = accum(ri,ti)+1;
            end
        end
        end
    end
    imagesc(accum);
    
    %% find local maxima in accumulator
    accumThresh = accum - thresh;
    accumThresh(logical(accumThresh<0)) = 0;
    accumMax = imregionalmax(accumThresh);
    imagesc(accumMax);
    
    %% calculate radius & angle of lines
    dist = [];
    ang = [];
    for t=1:size(accumMax,2)
        for r=1:size(accumMax,1)
        if accumMax(r,t)
            ang = [ang;(t-1)*angStep/180*pi];
            dist = [dist;(r-1)*distStep];
        end
        end
    end
    scatter(ang,dist);
    
    0 讨论(0)
  • 2021-02-06 09:07

    Maybe you need to think in terms of cleaning up the line you already have, rather than a Canny-like edge detection. It feels like you should be able to do something with image morphology, in particular I'm thinking of the skeletonize and ultimate eroded points type operations. Used appropriately these should remove from your image any features which are not 'lines' - I believe they're implemented in Intel's OpenCV library.

    You can recover a single line from your double line generated using the Canny filter using one dilate operation followed by 3 erodes (I tried it out in ImageJ) - this should also remove any edges.

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