如何根据凹度分割二进制图像?

时间:2015-07-11 16:34:33

标签: image matlab analysis

我有一个二进制图像,如:

enter image description here

我希望将主要的大椭圆形白色部分与顶部的小蘑菇云分开。这需要是许多不同图像的自动过程,这可能是完全不同的,但仍然具有主要斑点和在侧面或侧面上触摸较小斑点的这种特征。

我正在考虑使用分水岭,但根据额外斑点的比例,它并不适用于所有情况。我现在正试图看看是否有办法找到二进制图像的边缘并在这个边缘的凹度上设置一个条件,但我找不到如何做到这一点。

理想情况下在MATLAB中实现,但如果在SciPy / Mathematica中可以做得更好,那也很好。

2 个答案:

答案 0 :(得分:3)

这是我的尝试。代码是粗略的,但它是如何使用边界和有符号曲率来找到从身体的其余部分分割“蘑菇顶部”的两个点,然后使用转弯谓词来确定点的一般概念。兴趣。

ID  Col1    Col2    Col3    Col4
1   101     1000    0      10000
1   102     0       1000   10000

2   101     1000    0      10000
2   102     0       1000   10000

3   103     2000    0      500
3   104     0      250     500

4   101     1000    0      10000
4   102     0      1000    10000
4   103     500     0      10000

使用此图片:

enter image description here

输出:

enter image description here

答案 1 :(得分:3)

您可以使用水平和垂直直方图来分割蘑菇。请注意,代码非常简单:图像处理代码只有10-15行。

当蘑菇斑块与其他较小的斑点相连时,这种方法的优点是稳健(理论上,您需要在其他图像上进行测试),其中简单地保持最大的斑点或较长的轮廓可能导致错误。

代码中的注释应该澄清每一步,但如果不清楚,请发表评论。

close all; clear all;
img = imread('mushroom .jpg');

% Threshold
binary = img > 100;

% Apply open morphology operator to "enlarge" holes and remove small blobs
se = strel('disk',3);        
opened= imopen(binary, se);

% Compute vertical projection
projectionVer = sum(opened,1);

% Find max value on vertical projection
% Is basically the vertical simmetry axis of the mushroom
[~, centerX] = max(projectionVer);

% Find limits of the mushroom
% This procedure can be helpful if the central blob (the mushroom)
% is linked with the small left and right blobs.
% In this case simply taking the larget boundary, or the largest
% blob will fail. 
% But since you said "touching smaller blobs either above of to the
% sides"...

leftMin = min(projectionVer(1 : centerX));
rightMin = min(projectionVer(centerX+1 : end));
leftX = find(projectionVer(1 : centerX) == leftMin, 1, 'last');
rightX = find(projectionVer(centerX+1 : end) == rightMin, 1, 'first');
rightX = centerX + rightX;

% Crop the image to keep only the mushroom
mushroom = img(:, leftX : rightX);

% Compute horizontal projection on mushroom
projectionHor = sum(mushroom, 2);

% Find first minimum peak
[pks, loc] = findpeaks(- projectionHor);
minY = loc(1); % << You are looking for this!
minYVal = -pks(1);

% Segmentation
topY = find(projectionHor>0, 1);

result = uint8(opened);

% probably you can do better than for loops, but ok for now...
for y=leftX:rightX
    for x=topY:size(result ,1)
        if(opened(x,y))            
            if(x<=minY)
                %top
                result(x,y) = 127;
            else
                %bottom
                result(x,y) = 200;
            end
        end
    end
end

%Plotting

imshow(result);
figure();

subplot(221);
imshow(img);
title('Image');

subplot(222);
hold on;
plot(flip(projectionHor), (1 : length(projectionHor)));
plot(minYVal, size(img,1) - minY, 'or');
title('Horizontal Projection');
axis([0, +Inf, 0, size(img,1)]);
hold off;

subplot(223);
hold on;
plot(projectionVer);
plot(leftX, leftMin, 'or');
plot(rightX, rightMin, 'or');
title('Vertical Projection');
axis([0, size(img,2), 0, +Inf]);
hold off;

subplot(224);
imshow(img);
hold on;
plot((1:size(img,2)), ones(1,size(img,2))*minY, 'r'); 
plot(ones(1,size(img,1))*leftX, (1:size(img,1)), 'g');
plot(ones(1,size(img,1))*rightX, (1:size(img,1)), 'b');
title('Result');
hold off;

enter image description here enter image description here