如何分割天空和水中的一部分

时间:2013-11-28 15:08:00

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

我正试图在此图像中分割天空和水部分。

Link of the Picture 我已经尝试了很多方法,比如k-means,阈值,多门限等等。不幸的是,没有什么能运作得那么好。  这是我的代码(Matlab)的一个例子:

img=imread('1.jpg');
im_gray=rgb2gray(img);
b=imadjust(im_gray);
imshow(b);
bw_remove_small=imopen(b,strel('square',5));
imshow(bw_remove_small); %after 1st iteration
m3=medfilt2(bw_remove_small,[18,16]);
imshow(m3);
m3=medfilt2(bw_remove_small,20,20]);
m3=medfilt2(bw_remove_small,[20,20]);
imshow(m3);
I1=m3;
I2=rgb2gray(I1);
I=double(I2);
figure
subplot(1,3,1)
imshow(I1)
subplot(1,3,2)
imshow(I2)
g=kmeans(I(:),4);
J = reshape(g,size(I));
subplot(1,3,3)
imshow(J,[]);

任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

图片的两个区域的色调,纹理和灰度级亮度不同。

从我们的角度来看,地平线是图像中的最佳线,可以通过亮度的明显变化来看出。亮度不适用于单个阈值,因为图像亮度不平坦,因此使用亮度分布模型来平整天空或水。这意味着对目标的了解,但有两件事可以给你一个近似的答案:质地和/或色调。

阈值为120(源自色调直方图)的色调将为您提供两个区域,但不会干净地划分,并且会有重叠的部分。虽然使用这两个部分可以找到亮度模型。

与纹理相同。使用图像的一小部分,减去直流输出,然后平均或只是对非直流部分求和将产生具有两个峰值的直方图,这两个峰值可能与色调不同但足以找到阈值和两个允许找到亮度模型的区域。

关键的事实是,如果将天空正确地建模为灰色表面,那么您可以将其从图像中减去并使用简单的阈值将其拉出来。

在此图像中边缘检测非常嘈杂,以便能够轻松查看线条,但如果您可以在不丢失形状的情况下拉出图像线条,则可以查找直线和长轮廓,这样可能需要更少的代码/工作。

希望这会有所帮助!当天空和山脉之间没有太大差别时,我用它来寻找远处的山脉。另外,我只是在你的照片上尝试了这个,并且在没有良好的天空模型的情况下几乎得到了一个很好的答案。