如何使用BoofCV在Java中分水岭(分割)图像?

如何使用BoofCV在Java中分水岭(分割)图像?,java,image,markers,watershed,boofcv,Java,Image,Markers,Watershed,Boofcv,我正在尝试使用Java中BoofCV提供的分水岭函数分割一幅简单的图像。因此,我编写(复制、编辑和调整)了以下代码: package alltestshere; import boofcv.alg.filter.binary.BinaryImageOps; import boofcv.alg.filter.binary.Contour; import boofcv.alg.filter.binary.GThresholdImageOps; import boofcv.gui.ListDispl

我正在尝试使用Java中BoofCV提供的分水岭函数分割一幅简单的图像。因此,我编写(复制、编辑和调整)了以下代码:

package alltestshere;

import boofcv.alg.filter.binary.BinaryImageOps;
import boofcv.alg.filter.binary.Contour;
import boofcv.alg.filter.binary.GThresholdImageOps;
import boofcv.gui.ListDisplayPanel;
import boofcv.gui.binary.VisualizeBinaryData;
import boofcv.gui.image.ShowImages;
import boofcv.io.UtilIO;
import boofcv.io.image.ConvertBufferedImage;
import boofcv.io.image.UtilImageIO;
import boofcv.struct.ConnectRule;
import boofcv.struct.image.GrayS32;
import boofcv.struct.image.GrayU8;
import java.awt.image.BufferedImage;
import java.util.List;
import boofcv.alg.segmentation.watershed.WatershedVincentSoille1991;
import boofcv.factory.segmentation.FactorySegmentationAlg;
import boofcv.gui.feature.VisualizeRegions;



public class examp {

   public static void main( String args[] ) {
    // load and convert the image into a usable format
    BufferedImage image = UtilImageIO.loadImage(UtilIO.pathExample("C:\\\\Users\\\\Caterina\\\\Downloads\\\\boofcv\\\\data\\\\example\\\\shapes\\\\shapes02.png"));
    // convert into a usable format
    GrayU8 input = ConvertBufferedImage.convertFromSingle(image, null, GrayU8.class);

//declare some of my working data
    GrayU8 binary = new GrayU8(input.width,input.height);
    GrayS32 markers = new GrayS32(input.width,input.height);

    // Select a global threshold using Otsu's method.
    GThresholdImageOps.threshold(input, binary, GThresholdImageOps.computeOtsu(input, 0, 255),true);

    //through multiple erosion you can obtain the sure foreground and use it as marker in order to segment the image
    GrayU8 filtered = new GrayU8 (input.width, input.height);
    GrayU8 filtered2 = new GrayU8 (input.width, input.height);
    GrayU8 filtered3 = new GrayU8 (input.width, input.height);
    BinaryImageOps.erode8(binary, 1, filtered);
    BinaryImageOps.erode8(filtered, 1, filtered2);
    BinaryImageOps.erode8(filtered2, 1, filtered3);

//count how many markers you have (one for every foreground part +1 for the background
    int numRegions = BinaryImageOps.contour(filtered3, ConnectRule.EIGHT, markers).size()+1 ;


    // Detect foreground imagea using an 8-connect rule
    List<Contour> contours = BinaryImageOps.contour(binary, ConnectRule.EIGHT, markers);

    //Watershed function which takes the original b&w image as input and the markers 
    WatershedVincentSoille1991 watershed = FactorySegmentationAlg.watershed(ConnectRule.FOUR);
    watershed.process(input, markers);

    //get the results of the watershed as output
    GrayS32 output = watershed.getOutput();


    // display the results
    BufferedImage visualBinary = VisualizeBinaryData.renderBinary(input, false, null);
    BufferedImage visualFiltered = VisualizeBinaryData.renderBinary(filtered3, false, null);
    BufferedImage visualLabel = VisualizeBinaryData.renderLabeledBG(markers , contours.size(), null);
    BufferedImage outLabeled = VisualizeBinaryData.renderLabeledBG(output, numRegions, null);


    ListDisplayPanel panel = new ListDisplayPanel();
    panel.addImage(visualBinary, "Binary Original");
    panel.addImage(visualFiltered, "Binary Filtered");
    panel.addImage(visualLabel, "Markers");
    panel.addImage(outLabeled, "Watershed");
    ShowImages.showWindow(panel,"Watershed");
    }

}
package-alltestshere;
导入boofcv.alg.filter.binary.BinaryImageOps;
导入boofcv.alg.filter.binary.Contour;
导入boofcv.alg.filter.binary.GThresholdImageOps;
导入boofcv.gui.ListDisplayPanel;
导入boofcv.gui.binary.VisualizationBinaryData;
导入boofcv.gui.image.ShowImages;
进口boofcv.io.UtilIO;
导入boofcv.io.image.convertBuffereImage;
导入boofcv.io.image.UtilImageIO;
导入boofcv.struct.ConnectRule;
导入boofcv.struct.image.GrayS32;
导入boofcv.struct.image.GrayU8;
导入java.awt.image.buffereImage;
导入java.util.List;
进口boofcv.alg.segmentation.watershed.WatershedVincentSoille1991;
导入boofcv.factory.segmentation.FactorySegmentationAlg;
导入boofcv.gui.feature.visualized区域;
公开课考试{
公共静态void main(字符串参数[]){
//加载图像并将其转换为可用格式
BuffereImage=UtilIO.loadImage(UtilIO.pathExample(“C:\\\\Users\\\\Caterina\\\\Downloads\\\\boofcv\\\\data\\\\example\\\\\shapes02.png”);
//转换成可用的格式
GrayU8输入=ConvertBuffereImage.convertFromSingle(image,null,GrayU8.class);
//声明我的一些工作数据
GrayU8二进制=新的GrayU8(输入.宽度,输入.高度);
GrayS32标记=新的GrayS32(输入.宽度,输入.高度);
//使用大津的方法选择一个全局阈值。
阈值(输入,二进制,GThresholdImageOps.computeOtsu(输入,0255),真);
//通过多次侵蚀,你可以获得确定的前景,并将其用作标记,以便分割图像
GrayU8 filtered=新的GrayU8(input.width,input.height);
GrayU8 filtered2=新的GrayU8(input.width,input.height);
GrayU8 filtered3=新的GrayU8(input.width,input.height);
BinaryImageOps.8(二进制,1,过滤);
BinaryImageOps.8(过滤,1,过滤2);
二进制映像操作8(过滤器2、1、过滤器3);
//计算您有多少个标记(每个前景部分一个标记+背景1个标记)
int numRegions=BinaryImageOps.contour(filtered3,ConnectRule.EIGHT,markers).size()+1;
//使用8-connect规则检测前景图像A
列表轮廓=BinaryImageOps.contour(二进制,ConnectRule.8,标记);
//以原始黑白图像为输入的分水岭函数和标记
WatershedVincentSoille1991 watershed=工厂分段总分水岭(连接规则4);
流域。过程(输入、标记);
//获取流域的结果作为输出
GrayS32输出=流域。getOutput();
//显示结果
BuffereImage visualBinary=VisualizeBinaryData.renderBinary(输入,false,null);
BuffereImage visualFiltered=VisualizeBinaryData.renderBinary(filtered3,false,null);
BuffereImage visualLabel=VisualizeBinaryData.RenderLabelDBG(markers,contours.size(),null);
BuffereImage Unlabeled=VisualizationBinaryData.renderLabeledBG(输出,numRegions,null);
ListDisplayPanel=新建ListDisplayPanel();
面板addImage(可视化,“二进制原件”);
面板addImage(视觉过滤,“二进制过滤”);
面板addImage(可视标签,“标记”);
专家组:addImage(被列为“分水岭”);
ShowImages.showWindow(面板,“分水岭”);
}
}
然而,这段代码并不好用。具体来说,它不是用不同的颜色给前景对象上色,而是将所有图像分割成区域,而每个区域仅由一个前景对象和背景的一部分组成,并用相同的颜色绘制所有这部分(图3).那么,我做错了什么

我正在上传和

提前感谢,,
Katerina

之所以得到这个结果,是因为您没有将背景作为区域处理。您提供给分水岭的标记只是形状的轮廓。由于背景不是区域,分水岭算法将其平均分割到每个区域。这是因为每个形状的原始图像中到b的距离相等背景相同(二进制图像)


如果要将背景作为另一个区域获取,请向分水岭算法提供背景的一些点作为标记,例如角点。

非常感谢!我这样做了,实际上我得到了更好的结果!:-)