我有这样的图像:
我想要做的是找到这个单元格的外边缘和单元格中不同颜色的两个部分之间的内边缘。
但是这个图像包含了我想的很多细节,有没有办法简化这个图像,删除那些小边缘并找到我想要的边缘?
我尝试过matlab提供的边缘函数。但它只能找到外边缘并受到那些细节边缘的干扰。
答案 0 :(得分:2)
在我看来,你在图像中有三种主色:
1.蓝色背景(但也在细胞内呈现为“噪音”)
2. grenn-ish细胞的一部分
3. red-ish - 细胞的第二部分
如果这三种颜色足够清晰,您可以尝试使用k-means和Graph cut来分割图像。
第一阶段 - 使用k-means将每个像素与三种主色中的一种相关联。将k-means应用于图像的颜色(每个像素在您选择的颜色空间中是一个3向量)。使用k=3
运行k-means,为每个像素保留其与质心的距离。
第二阶段 - 将细胞与背景分开。使用图形切割进行二进制分割。每个像素的数据成本是到背景颜色的距离(如果像素标记为“背景”),或者到其他两种颜色的最小距离(如果像素标记为“前景”)。使用图像对比度为平滑项设置成对权重。
第三阶段 - 将细胞的两个部分分开。再次使用图形切割进行二进制分割,但这次仅适用于前一阶段标记为“单元格”的像素。对于所有标签,k均值分配给背景但标记为单元格的像素的数据项应为零(这些是单元格内的“噪声”像素)。
您可能会发现我的matlab wrapper for graph-cuts对此任务很有用。
答案 1 :(得分:2)
由于边界模糊,红色和绿色强度之间的微小差异,这是一项非常具有挑战性的工作。如果你想非常精确地实现分割并满足一些医疗要求,Shai的k-means加graph cuts可能是极少数选项之一(EM algorithm可能是另一种选择)。如果您有一个包含许多相似图像的大型数据库,则某些machine learning methods可能有所帮助。否则,我只是写了一个非常简单的代码来粗略地为你提取内部红色区域。边界不准确,因为还包括一些绿色区域。
I1=I;
I=rgb2hsv(I);
I=I(:,:,1); % the channel with relatively large margin between green and red
I=I.*(I<0.25);
I=imdilate(I, true(5));
% I=imfill(I,'holes'); depends on what is your definition of the inner boundary
bw=bwconncomp(I);
ar=bw.PixelIdxList;
% find the largest labeled area,
n=0;
for i=1:length(ar)
if length(ar{i})>n
n=length(ar{i});
num=i;
end
end
bw1=bwlabel(I);
bwfinal(:,:,1)=(bw1==num).*double(I1(:,:,1));
bwfinal(:,:,2)=(bw1==num).*double(I1(:,:,2));
bwfinal(:,:,3)=(bw1==num).*double(I1(:,:,3));
bwfinal=uint8(bwfinal);
imshow(bwfinal)