【问题标题】:How to programatically perform image segmentation in real-time如何以编程方式实时执行图像分割
【发布时间】:2015-04-28 18:13:44
【问题描述】:

我目前正在尝试分割血管的超声图像(视频帧),例如正下方的那个。

在饱和通道上使用一个简单的二元滤波器(下面的代码),我可以得到一个不令人满意的结果,例如下面的第三张图片。当然,我尝试使用 OpenCV Imgproc.dilate() 将过滤区域扩大几个像素,但这样做的问题是它增加了将过滤区域与相邻黑色区域连接的机会,这会导致不可接受的精度损失后续计算。

如果在这种分割方面有经验的人能够向我指出一种很好的技术,可以实时(30 帧/秒)实现接近下面第二张图像的效果,那就太好了!


如何分割这个基础图像:

所以看起来更像是这种手绘分割:

虽然饱和通道上的简单二元滤波器不是那么好:

我的饱和度过滤函数(java):

public static Mat threshold_onsat (Mat frame, Mat hsv_frame, int saturation){
    double sat = (double) saturation;
    List<Mat> lhsv = new ArrayList<Mat>(3);
    Mat masked = new Mat();
    Core.split(hsv_frame, lhsv);
    Mat sat_mask = lhsv.get(1);
    Imgproc.threshold(sat_mask, sat_mask, sat, 255D, Imgproc.THRESH_BINARY_INV);
    frame.copyTo(masked, sat_mask);
    return masked;
}

【问题讨论】:

  • 这真的很酷,问题也很好,但只想指出一点:我有一个朋友正在攻读一个非常相似的主题的博士学位。我想说的是,如果有人至少要工作 3 年才能让这样的东西正常工作,你可能无法得到这个问题的答案。祝你好运
  • 建议:搜索医学图像分割的文献。关卡集是一种常见的方法。
  • @AnderBiguri 是的,我确实意识到了这一点。但是,我认为无论如何都值得问。尝试没有成本,对吧? :-) 感谢您的建议!
  • 选择自动分割的重心作为起点。从那里向外部发射光线并绘制强度值。 Ma也许您在放置手动分割的区域周围看到了一些“模式变化”。

标签: opencv image-processing computer-vision image-segmentation


【解决方案1】:

由于有人将此问题添加到他的收藏夹中,我将发布我的最佳线索:

这类问题的最佳解决方案确实似乎是主动轮廓分割,为此我找到了洛桑理工学院生物医学成像组的this Esnake implementation。它是一个 ImageJ 插件,但我希望能够将它实现到我自己的应用程序中。

【讨论】:

    【解决方案2】:

    我认为您可以继续使用当前的饱和度过滤器,因为它可以识别您所在的地区。但是然后使用形态学操作对其进行扩充。我会先使用腐蚀,然后再使用膨胀。 (不仅仅是您尝试过的自行膨胀)。腐蚀步骤消除了噪声,然后膨胀使蒙版变大。实际上,我连续进行了两次扩张,以创建一个更好看的蒙版。

    我在 matlab 中做了一个快速测试作为概念证明。我只使用 matlab 是因为它的测试速度非常快(约 5 分钟),但我知道 openCV 具有非常相似的功能(膨胀/侵蚀元素、imerode、imdilate)。阅读代码 cmets,有一些关于该过程的好信息。代码本身并不重要,仅供参考。更重要的部分是了解它的作用。我试图将我的“面具”与你的面具相匹配,但我根本没有使用你的轮廓区域。

    segmented_im = rgb2gray(imread('binary_saturation_image.png'));
    segmented_im = segmented_im(3:end,:);
    orig_im = rgb2gray(imread('base_image.png'));
    
    %i recreated your mask here, it looked like your mask had 0 values so thats
    %what i used. it's 1 in region of interest and 0 elsewhere, this is
    %important to take note of
    mask = (segmented_im==0);
    
    %creates a structuing element for our morphological operators, Another way
    %to thing of this is like a nearest neighbor operation. This structuring
    %element defines what your neighbors are, we are using a disk with radius 7
    % in openCV this is your erosion/dilation element, the closest would be MORPH_ELLIPSE
    %but using different elements and sizes may you get a better shape
    %also using different shapes for the erosion vs dilation may help you
    %further shape your mask
    se = strel('disk',7,0);
    
    %now we erode the image (this expands the 0 regions) we do this to remove
    %noise, those small little dots around the mask
    mask_erode = imerode(mask,se);
    
    %now we dilate the image (expands the 1 regions) this will give us a more
    %rounded mask
    mask_dilate1 = imdilate(mask_erode,se);
    
    %we do it one more time to round out the shape more
    mask_dilate2 = imdilate(mask_dilate1,se);
    
    %now we invert the mask (so the areas of interest are 0, and 1 elsewhere)
    invert_mask = uint8(~mask_dilate2);
    
    %we multiply the original image by our mask (so the area of interest has
    %zero values)
    newly_segmented = orig_im .* invert_mask;
    
    
    figure()
    subplot(2,3,1);imshow(orig_im);title('base image');
    subplot(2,3,2);imshow(mask);title('mask');
    subplot(2,3,3);imshow(mask_erode);title('mask erode image');
    subplot(2,3,4);imshow(mask_dilate1);title('mask dilate1 image');
    subplot(2,3,5);imshow(mask_dilate2);title('mask dilate2 image');
    subplot(2,3,6);imshow(newly_segmented);title('newly segmented image');
    

    【讨论】:

      【解决方案3】:

      我认为您可能想了解一种称为活动形状的更复杂的方法。虽然我不是医学图像处理方面的专家,但我知道我的一个朋友已经成功地使用了这种方法来分割腹部动脉瘤的内外表面(哎哟),这似乎与您的应用松散相关。您可以找到有关主题in this paper 的更多信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-03
        • 1970-01-01
        • 2015-03-14
        • 2020-02-11
        • 1970-01-01
        • 2011-11-12
        • 1970-01-01
        • 2017-01-28
        相关资源
        最近更新 更多