我正在尝试设计一种方法来检测此管道的曲率。我尝试应用hough变换,发现了检测到的线,但是它们并不沿着管道表面放置,因此无法平滑以适应beizer曲线。请为这种图像提供一些好的开始方法。[

通过霍夫变换获得的用于检测线条的图像如下
[
我正在使用标准Matlab代码进行概率霍夫变换线检测,该检测生成围绕结构的线段。本质上,管道的形状类似于抛物线,但是对于霍夫抛物线检测,我需要在检测之前提供该点的偏心率。请提出一种很好的方法来找到沿着曲率的离散点,这些离散点可以拟合到抛物线。我已经给opencv和ITK加上了标签,所以如果有可以在这张特定图片上实现的功能,请建议我尝试一下该功能以查看结果。

img = imread('test2.jpg');
rawimg = rgb2gray(img);
 [accum, axis_rho, axis_theta, lineprm, lineseg] = Hough_Grd(bwtu, 8, 0.01);
figure(1); imagesc(axis_theta*(180/pi), axis_rho, accum); axis xy;
 xlabel('Theta (degree)'); ylabel('Pho (pixels)');
 title('Accumulation Array from Hough Transform');
  figure(2); imagesc(bwtu); colormap('gray'); axis image;
  DrawLines_2Ends(lineseg);
  title('Raw Image with Line Segments Detected');

图像的边缘图如下algorithm - 使用图像处理(霍夫变换抛物线检测)计算弯管的曲率-LMLPHP,在边缘图上进行霍夫变换后产生的结果也不佳。我当时在考虑一种解决方案,该解决方案可以像曲线一样表示一般参数形状检测,可以表示为抛物线族,因此我们进行曲线拟合以估计系数的弯曲度,以分析其曲率。我需要设计一个实时程序,所以请向这个方向提出建议。 algorithm - 使用图像处理(霍夫变换抛物线检测)计算弯管的曲率-LMLPHP

最佳答案

我建议采用以下方法:

第一步:生成管道的分段。

  • 对图像执行阈值处理。
  • 在阈值图像中查找连接的组件。
  • 搜索表示管道的已连接组件。
    代表管道的已连接组件应具有被划分为顶部和底部边缘的边缘贴图(请参见随附的图像)。
    顶部和底部边缘的大小应相似,并且彼此之间应具有相对恒定的距离。换句话说,它们每像素距离的方差应该很小。

  • algorithm - 使用图像处理(霍夫变换抛物线检测)计算弯管的曲率-LMLPHP

    第二阶段-提取曲线​​

    在此阶段,您应该提取曲线的点以执行Beizer拟合。
    您可以在顶部边缘或底部边缘执行此计算。
    另一个选择是在管道分段的骨架上执行此操作。

    结果

    管道分段。顶部和底部边缘分别用蓝色和红色标记。

    algorithm - 使用图像处理(霍夫变换抛物线检测)计算弯管的曲率-LMLPHP

    代码
    I = mat2gray(imread('ILwH7.jpg'));
    im = rgb2gray(I);
    
    %constant values to be used later on
    BW_THRESHOLD = 0.64;
    MIN_CC_SIZE = 50;
    VAR_THRESHOLD = 2;
    SIMILAR_SIZE_THRESHOLD = 0.85;
    
    %stage 1 - thresholding & noise cleaning
    bwIm = im>BW_THRESHOLD;
    bwIm = imfill(bwIm,'holes');
    bwIm = imopen(bwIm,strel('disk',1));
    
    
    CC = bwconncomp(bwIm);
    %iterates over the CC list, and searches for the CC which represents the
    %pipe
    for ii=1:length(CC.PixelIdxList)
        %ignore small CC
        if(length(CC.PixelIdxList{ii})<50)
            continue;
        end
        %extracts CC edges
        ccMask = zeros(size(bwIm));
        ccMask(CC.PixelIdxList{ii}) = 1;
        ccMaskEdges = edge(ccMask);
    
        %finds connected components in the edges mat(there should be two).
        %these are the top and bottom parts of the pipe.
        CC2 = bwconncomp(ccMaskEdges);
        if length(CC2.PixelIdxList)~=2
            continue;
        end
    
        %tests that the top and bottom edges has similar sizes
        s1 = length(CC2.PixelIdxList{1});
        s2 = length(CC2.PixelIdxList{2});
        if(min(s1,s2)/max(s1,s2) < SIMILAR_SIZE_THRESHOLD)
            continue;
        end
    
        %calculate the masks of these two connected compnents
        topEdgeMask = false(size(ccMask));
        topEdgeMask(CC2.PixelIdxList{1}) = true;
        bottomEdgeMask = false(size(ccMask));
        bottomEdgeMask(CC2.PixelIdxList{2}) = true;
    
        %tests that the variance of the distances between the points is low
        topEdgeDists = bwdist(topEdgeMask);
        bottomEdgeDists = bwdist(bottomEdgeMask);
        var1 = std(topEdgeDists(bottomEdgeMask));
        var2 = std(bottomEdgeDists(topEdgeMask));
    
        %if the variances are low - we have found the CC of the pipe. break!
        if(var1<VAR_THRESHOLD && var2<VAR_THRESHOLD)
            pipeMask = ccMask;
            break;
        end
    
    
    end
    
    %performs median filtering on the top and bottom boundaries.
    MEDIAN_SIZE =5;
    [topCorveY, topCurveX] = find(topEdgeMask);
    topCurveX = medfilt1(topCurveX);
    topCurveY = medfilt1(topCurveY);
    [bottomCorveY, bottomCurveX] = find(bottomEdgeMask);
    bottomCurveX = medfilt1(bottomCurveX);
    bottomCorveY = medfilt1(bottomCorveY);
    
    %display results
    imshow(pipeMask); hold on;
    plot(topCurveX,topCorveY,'.-');
    plot(bottomCurveX,bottomCorveY,'.-');
    

    评论
  • 在此特定示例中,通过阈值获取管道分段相对容易。在某些情况下,它可能会更复杂。在这些情况下,您可能需要使用区域增长算法来生成管道分段。
  • 通过使用其他一些技巧,可以检测代表管道的已连接组件。例如,其边界的局部曲率应较低。
  • 10-08 08:19
    查看更多