1、GrabCut人为干预分割前景
/// <summary>
/// 检测边缘并标注(GrabCut人为干预分割前景;速度比分水岭算法慢,结果准确性高)
/// </summary>
/// <param name="img">图片</param>
/// <param name="rect">前景物体矩形区域;new Rect(100, 100, 200, 200)</param>
/// <param name="dstMat">结果图片</param>
/// <param name="bgdModel">背景图</param>
/// <param name="fgdModel">前景图</param>
/// <param name="iterCount">迭代次数</param>
/// <param name="mode">初始化的模式;默认为矩形初始化</param>
public static Mat GrabCut(Mat img, Rect rect, out Mat dstMat,
    out Mat bgdModel, out Mat fgdModel, int iterCount = 1, GrabCutModes mode = GrabCutModes.InitWithRect)
{
    Mat dstMat1 = new Mat();

    dstMat = new Mat();
    bgdModel = new Mat();
    fgdModel = new Mat();

    Cv2.GrabCut(img, dstMat, rect, bgdModel, fgdModel, iterCount, mode);
    Cv2.Compare(img, dstMat, dstMat1, CmpType.EQ);

    return dstMat1;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
2、漫水填充分割
/// <summary>
/// 检测边缘并标注(漫水填充;类似于PS的魔术棒,适合于对二值图处理)
/// </summary>
/// <param name="image">图片/结果图片</param>
/ <param name="mask">操作掩码;但是不会填充非零像素</param>
/// <param name="seedPoint">起始点</param>
/// <param name="newVal">被染色的值</param>
/// <param name="rect">设置重绘区域的最小边界矩形区域</param>
/// <param name="loDiff">最小色差值</param>
/// <param name="upDiff">最大色差值</param>
/// <param name="flags">操作标志位</param>
/// <returns></returns>
public static int FloodFill(InputOutputArray image, Point seedPoint, Scalar newVal, out Rect rect,
    Scalar? loDiff = null, Scalar? upDiff = null, FloodFillFlags flags = FloodFillFlags.Link4)
    => Cv2.FloodFill(image, seedPoint, newVal, out rect, loDiff, upDiff, flags);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
3、分水岭分割
/// <summary>
/// 分水岭分割
/// </summary>
/// <param name="image">图片</param>
/// <param name="markers">掩码</param>
/// <returns></returns>
public static void Watershed(InputArray image, InputOutputArray markers) => Cv2.Watershed(image, markers);
/// <summary>
/// 检测边缘并标注(分水岭分割)
/// 先在外面找边缘-比如:先图像灰度化、再滤波、再Canny边缘检测;如使用MarginDetector_Sobel或者MarginDetector_Canny
/// 再传入原始图像和边缘信息
/// </summary>
/// <param name="image">图片</param>
/// <param name="points">轮廓集合</param>
/// <param name="hierarchy">历史轮廓</param>
/// <returns></returns>
public static Mat Watershed_Draw(Mat image, Point[][] points, HierarchyIndex[] hierarchy)
{
    Mat imageContours = Mat.Zeros(image.Size(), MatType.CV_8UC1);  // 轮廓
    Mat markers = new Mat(image.Size(), MatType.CV_32S);  // 第二个参数

    for (int index = 0; index < hierarchy.Length; index++)
    {
        Cv2.DrawContours(markers, points, index, Scalar.All(index + 1), 1, LineTypes.Link8, hierarchy);
        Cv2.DrawContours(imageContours, points, index, new Scalar(255), 1, LineTypes.Link8, hierarchy);
    }

    // 分水岭分割
    Cv2.Watershed(image, markers);

    // 填充颜色
    Mat perspectiveImage = new Mat(image.Size(), MatType.CV_8UC3);
    for (int i = 0; i < markers.Size().Height; i++)
    {
        for (int j = 0; j < markers.Size().Width; j++)
        {
            int index = markers.At<int>(i, j);
            if (index == -1)
            {
                perspectiveImage.At<Vec3b>(i, j) = new Vec3b(255, 255, 255);
            }
            else
            {
                perspectiveImage.At<Vec3b>(i, j) = RandomColor(index);
            }
        }
    }
    Mat wshed = new Mat();
    Cv2.AddWeighted(image, 0.4, perspectiveImage, 0.6, 0, wshed);
    return wshed;
}

/// <summary>
/// 随机颜色
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
private static Vec3b RandomColor(int index)
{
    int value = index % 255;  // 0~255随机数

    Random random = new Random();
    byte aa = Convert.ToByte(random.Next(0, value));
    byte bb = Convert.ToByte(random.Next(0, value));
    byte cc = Convert.ToByte(random.Next(0, value));

    return new Vec3b(aa, bb, cc);
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.

作者:꧁执笔小白꧂