Image 如何有效地为这张显微图像创建BW遮罩?
所以有一些背景。我的任务是编写一个matlab程序来计算可见光显微镜图像中酵母细胞的数量。要做到这一点,我认为第一步将是细胞分割。在得到真实的实验图像集之前,我开发了一种算法,使用分水岭的测试图像集。看起来是这样的: 分水岭的第一步是为单元生成BW掩码。然后,我将生成一个bwdist图像,其中包含从BW掩码生成的强制局部最小值。有了它,我可以很容易地生成分水岭 正如您所见,我的算法依赖于BW掩码的成功生成。因为我需要从中生成bwdist图像和标记。最初,我按照以下步骤生成BW掩码:Image 如何有效地为这张显微图像创建BW遮罩?,image,matlab,image-processing,image-segmentation,watershed,Image,Matlab,Image Processing,Image Segmentation,Watershed,所以有一些背景。我的任务是编写一个matlab程序来计算可见光显微镜图像中酵母细胞的数量。要做到这一点,我认为第一步将是细胞分割。在得到真实的实验图像集之前,我开发了一种算法,使用分水岭的测试图像集。看起来是这样的: 分水岭的第一步是为单元生成BW掩码。然后,我将生成一个bwdist图像,其中包含从BW掩码生成的强制局部最小值。有了它,我可以很容易地生成分水岭 正如您所见,我的算法依赖于BW掩码的成功生成。因为我需要从中生成bwdist图像和标记。最初,我按照以下步骤生成BW掩码: 生成图
背景已完成。这是我的问题
但今天我收到了新的真实数据集。图像分辨率小得多,光照条件与测试图像集不同。颜色深度也要小得多。这些使我的算法毫无用处。这是: 使用stdfilt无法生成良好的干净图像。相反,它会生成如下内容(注意:我已经调整了stdfilt函数的参数和BW阈值,下面是我能得到的最佳结果): 正如你所看到的,细胞中心有一些光像素,不一定比细胞膜暗。这导致bw阈值生成如下内容: bw阈值化后的新bw图像具有不完整的膜或分割的细胞中心,使其不适合其他步骤 我最近才开始做图像处理,不知道该怎么做。如果你有主意,请帮帮我!谢谢
为了您的方便,我附上了dropbox的链接,我认为您的方法存在一个根本问题。您的算法使用
stdfilt
对图像进行二值化。但这本质上意味着你假设在背景和细胞内有低“纹理”。这适用于您的第一张图像。但是,在第二张图像中,单元中有一个“纹理”,因此这一假设被打破
我认为一个更有力的假设是,每个单元格周围都有一个“环”(对你发布的两张图片都有效)。所以我采取了探测这个戒指的方法
因此,我的方法基本上是:
cell=im2double(imread('cell1.png');
if(大小(单元格,3)=3)
单元=rgb2gray(单元);
结束
图(1),子批次(3,2,1)
imshow(cell,[]);
%检测边缘
hw=5;
cell_filt=imfilter(cell,fspecial('log',2*hw+1,1));
子地块(3,2,2)
imshow(cell_filt,[]);
%首先移除硬件并过滤掉非单元硬件
掩码=单元过滤器>0;
hw=5;
掩码=掩码(hw:end-hw-1,hw:end-hw-1);
子地块(3,2,3)
imshow(mask,[]);
rp=区域属性(遮罩、“像素idxlist”、“区域”);
rp=rp(垂直猫(相对面积)>50和垂直猫(相对面积)<2000);
掩码(:)=假;
掩码(vertcat(rp.PixelIdxList))=真;
子地块(3,2,4)
imshow(mask,[]);
%现在填充对象
mask1=真(尺寸(遮罩)+hw);
mask1(hw+1:end,hw+1:end)=掩码;
mask1=imfill(mask1,“孔”);
mask1=mask1(hw+1:结束,hw+1:结束);
mask2=真(尺寸(遮罩)+hw);
mask2(hw+1:end,1:end hw)=掩码;
mask2=imfill(mask2,“孔”);
mask2=mask2(hw+1:end,1:end hw);
mask3=真(大小(掩码)+hw);
mask3(1:end-hw,1:end-hw)=掩码;
mask3=imfill(mask3,“孔”);
mask3=mask3(1:end hw,1:end hw);
mask4=真(大小(掩码)+hw);
mask4(1:end-hw,hw+1:end)=掩码;
mask4=imfill(mask4,“孔”);
mask4=mask4(1:end hw,hw+1:end);
mask=mask1 | mask2 | mask3 | mask4;
%再次过滤大区域和小区域
rp=区域属性(遮罩、“像素idxlist”、“区域”);
rp=rp(垂直猫(相对面积)>100和垂直猫(相对面积)<5000);
掩码(:)=假;
掩码(vertcat(rp.PixelIdxList))=真;
子地块(3,2,5)
imshow(mask);
%过滤掉具有大量正凹度的区域
%获得边界
[B,L]=边界(掩码);
%边界上的圈
对于i=1:长度(B)
b=b{i};
%滤波器边界-使用循环卷积
b(:,1)=cconv(b(:,1),f特殊('gaussian',[17],1'),大小(b,1));
b(:,2)=cconv(b(:,2),f特殊('gaussian',[17],1'),大小(b,1));
%求曲率
曲线=零(尺寸b
cell = im2double(imread('cell1.png'));
if (size(cell,3) == 3)
cell = rgb2gray(cell);
end
figure(1), subplot(3,2,1)
imshow(cell,[]);
% Detect edges
hw = 5;
cell_filt = imfilter(cell, fspecial('log',2*hw+1,1));
subplot(3,2,2)
imshow(cell_filt,[]);
% First remove hw and filter out noncell hws
mask = cell_filt > 0;
hw = 5;
mask = mask(hw:end-hw-1,hw:end-hw-1);
subplot(3,2,3)
imshow(mask,[]);
rp = regionprops(mask, 'PixelIdxList', 'Area');
rp = rp(vertcat(rp.Area) > 50 & vertcat(rp.Area) < 2000);
mask(:) = false;
mask(vertcat(rp.PixelIdxList)) = true;
subplot(3,2,4)
imshow(mask,[]);
% Now fill objects
mask1 = true(size(mask) + hw);
mask1(hw+1:end, hw+1:end) = mask;
mask1 = imfill(mask1,'holes');
mask1 = mask1(hw+1:end, hw+1:end);
mask2 = true(size(mask) + hw);
mask2(hw+1:end, 1:end-hw) = mask;
mask2 = imfill(mask2,'holes');
mask2 = mask2(hw+1:end, 1:end-hw);
mask3 = true(size(mask) + hw);
mask3(1:end-hw, 1:end-hw) = mask;
mask3 = imfill(mask3,'holes');
mask3 = mask3(1:end-hw, 1:end-hw);
mask4 = true(size(mask) + hw);
mask4(1:end-hw, hw+1:end) = mask;
mask4 = imfill(mask4,'holes');
mask4 = mask4(1:end-hw, hw+1:end);
mask = mask1 | mask2 | mask3 | mask4;
% Filter out large and small regions again
rp = regionprops(mask, 'PixelIdxList', 'Area');
rp = rp(vertcat(rp.Area) > 100 & vertcat(rp.Area) < 5000);
mask(:) = false;
mask(vertcat(rp.PixelIdxList)) = true;
subplot(3,2,5)
imshow(mask);
% Filter out regions with lots of positive concavity
% Get boundaries
[B,L] = bwboundaries(mask);
% Cycle over boundarys
for i = 1:length(B)
b = B{i};
% Filter boundary - use circular convolution
b(:,1) = cconv(b(:,1),fspecial('gaussian',[1 7],1)',size(b,1));
b(:,2) = cconv(b(:,2),fspecial('gaussian',[1 7],1)',size(b,1));
% Find curvature
curv_vec = zeros(size(b,1),1);
for j = 1:size(b,1)
p_b = b(mod(j-2,size(b,1))+1,:); % p_b = point before
p_m = b(mod(j,size(b,1))+1,:); % p_m = point middle
p_a = b(mod(j+2,size(b,1))+1,:); % p_a = point after
dx_ds = p_a(1)-p_m(1); % First derivative
dy_ds = p_a(2)-p_m(2); % First derivative
ddx_ds = p_a(1)-2*p_m(1)+p_b(1); % Second derivative
ddy_ds = p_a(2)-2*p_m(2)+p_b(2); % Second derivative
curv_vec(j+1) = dx_ds*ddy_ds-dy_ds*ddx_ds;
end
if (sum(curv_vec > 0)/length(curv_vec) > 0.4 || std(curv_vec) > 2.0)
L(L == i) = 0;
end
end
mask = L ~= 0;
subplot(3,2,6)
imshow(mask,[])