Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 如何以编程方式实时执行图像分割_Opencv_Image Processing_Computer Vision_Image Segmentation - Fatal编程技术网

Opencv 如何以编程方式实时执行图像分割

Opencv 如何以编程方式实时执行图像分割,opencv,image-processing,computer-vision,image-segmentation,Opencv,Image Processing,Computer Vision,Image Segmentation,我目前正在尝试分割血管的超声图像(视频帧),比如下面的图像 在饱和通道上使用一个简单的二进制滤波器(下面的代码),我可以得到一个不满意的结果,如下面的第三幅图像。当然,我尝试用OpenCVImgproc.displate()将过滤区域放大几个像素,但问题是这会增加过滤区域与相邻黑色区域连接的机会,这会导致后续计算中无法接受的精度损失 如果有人在这种分割方面有经验,请告诉我一种很好的技术,可以实时(30帧/秒)接近下面的第二幅图像,那就太好了 如何分割此基础图像: 所以它看起来更像是手绘的分割

我目前正在尝试分割血管的超声图像(视频帧),比如下面的图像

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

如果有人在这种分割方面有经验,请告诉我一种很好的技术,可以实时(30帧/秒)接近下面的第二幅图像,那就太好了


如何分割此基础图像:

所以它看起来更像是手绘的分割:

虽然饱和信道上的简单二进制滤波器不是很好:

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

公共静态Mat阈值(Mat帧、Mat hsv帧、int饱和){
双饱和=(双)饱和;
列表lhsv=新阵列列表(3);
屏蔽垫=新垫();
分体式(hsv_框架,lhsv);
Mat sat_mask=lhsv.get(1);
Imgproc.threshold(sat_掩码,sat_掩码,sat,255D,Imgproc.THRESH_二进制\u INV);
frame.copyTo(蒙版、sat_蒙版);
返回蒙面;
}

我想您可能想看看一种更复杂的方法,称为“活动形状”。虽然我不是医学图像处理方面的专家,但我知道我的一个朋友已经成功地将这种方法用于腹部动脉瘤(ouch)内外表面的分割,这似乎与您的应用无关。您可以找到有关该主题的更多信息。

我认为您可以坚持使用当前的饱和度过滤器,因为它可以识别您所在的区域。然后用形态学运算来增强它。我会先腐蚀,然后扩张。(不只是像你尝试的那样自行扩张)。腐蚀步骤消除了噪声,然后膨胀使掩模变大。我实际上连续做了两次扩容,以创造一个好看的面具

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

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');

既然有人在他的FAV中添加了这个问题,我将发布我的最佳线索:


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

这真的很酷,问题也没什么,但我只想指出一件事:我有一个朋友在做一个类似主题的博士学位。我想说的是,如果有人愿意工作至少3年,让这样的东西正常工作,你可能无法得到这个问题的答案。好的luckAs建议:搜索医学图像分割的文献。水平集是一种常见的方法。@AnderBiguri是的,我知道这一点。不过,我觉得还是值得一问。尝试无需花费,对吗?:-)谢谢你的建议!选择自动分割的重心作为起点。从那里向外发射光线并绘制强度值。MaMaybe您可能会在手动分割区域周围看到一些“模式变化”。
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');