分水岭算法的原理大概就是在需要被区分的各个区域注入不同的颜色的水,这个水会染色它标志处的点,然后还会染色相邻的像素值差不多的点,不断漫延到像素值差异大的点停止。
public void Run()
{
Mat src = Cv2.ImRead("./Data/Image/lumu.jpg");
Console.WriteLine("用鼠标 标记前景,然后按键盘任意键。");
Cv2.ImShow("src", src);
Cv2.SetMouseCallback("src", MyMouseCallback);
Cv2.WaitKey();
Mat imgMask = new Mat(src.Size(), MatType.CV_8U, Scalar.Black);
imgMask.Rectangle(new Rect(1, 1, imgMask.Width - 2, imgMask.Height - 2), new Scalar(255));
foreach (var pp in p)
{
imgMask.Circle(pp, 3, new Scalar(1), -1);
}
Console.WriteLine("用鼠标 标记被分割的背景,然后按键盘任意键。");
Cv2.ImShow("src", src);
Cv2.SetMouseCallback("src", MyMouseCallbackbg);
Cv2.WaitKey();
foreach (var pp in p2)
{
imgMask.Circle(pp, 3, new Scalar(200), -1);
}
imgMask.ConvertTo(imgMask, MatType.CV_32S);
Cv2.Watershed(src, imgMask);
Mat mask = new Mat();
imgMask.ConvertTo(mask, MatType.CV_8U);
mask = mask.Threshold(100, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
Mat dst = Mat.Zeros(src.Height, src.Width, MatType.CV_8UC3);
src.CopyTo( dst, mask);
Cv2.ImShow("dst", dst);
Cv2.WaitKey();
}
readonly List<Point> p = new List<Point>();
readonly List<Point> p2 = new List<Point>();
private void MyMouseCallback(MouseEventTypes e, int x, int y, MouseEventFlags f, IntPtr Data)
{
if (e == MouseEventTypes.LButtonDown)
{
Console.WriteLine(x + ":" + y);
p.Add(new Point(x, y));
}
}
private void MyMouseCallbackbg(MouseEventTypes e, int x, int y, MouseEventFlags f, IntPtr Data)
{
if (e == MouseEventTypes.LButtonDown)
{
Console.WriteLine(x + ":" + y);
p2.Add(new Point(x, y));
}
}