
using OpenCvSharp;
using OpenCvSharp.Extensions;
using DlibDotNet;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
namespace app
{
public partial class FrmMain : Form
{
public FrmMain()
{
InitializeComponent();
}
/// <summary>
/// 分水岭
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnWatershed_Click(object sender, EventArgs e)
{
//展示图
Mat src = Cv2.ImRead(@"img\five.png");
Cv2.ImShow("原图", src);
// 标记图
// 灰度图片
Mat marker_src = new Mat();
Cv2.CvtColor(src, marker_src, ColorConversionCodes.BGR2GRAY);
// 均值滤波
Cv2.Blur(marker_src, marker_src, new OpenCvSharp.Size(5, 5), new OpenCvSharp.Point(-1, -1));
// 降噪
Cv2.Threshold(marker_src, marker_src, 100, 255, ThresholdTypes.BinaryInv);
var kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(12, 12));
// 形态学操作
// 闭运算,去除图像中的小黑点
Cv2.MorphologyEx(marker_src, marker_src, MorphTypes.Close, kernel);
Mat distance_img = new Mat();
// 距离变换
Cv2.DistanceTransform(marker_src, distance_img, DistanceTypes.L1, DistanceTransformMasks.Mask3, 5);
// 归一化
Cv2.Normalize(distance_img, distance_img, 0, 1.0, NormTypes.MinMax);
// 二值化
Cv2.Threshold(distance_img, distance_img, 0.5, 1, ThresholdTypes.Binary);
distance_img.ConvertTo(distance_img, MatType.CV_8UC1);
Cv2.ImShow("distance_img", distance_img * 10000);
// 找轮廓
Cv2.FindContours(distance_img, out OpenCvSharp.Point[][] contours, out HierarchyIndex[] outputArray, RetrievalModes.External, ContourApproximationModes.ApproxSimple);
Scalar color = new Scalar(255, 0, 0);
// 标记 前景markers。标记注水点。
Mat marker_all = Mat.Zeros(marker_src.Size(), MatType.CV_32SC1);
// Draw the foreground markers
for (int i = 0; i < contours.Length; i++)
{
// 对各个标记区域填充不同的像素值,后阶段根据像素值区分区域。
Cv2.DrawContours(marker_all, contours, (int)i, new Scalar((int)i + 1), -1);
}
//int num = contours.Length;
//MessageBox.Show(num.ToString());
// 标记 背景markers。Draw the background markers
// 画一个圆
Cv2.Circle(marker_all, new OpenCvSharp.Point(15, 15), 10, new Scalar(255), -1);
Mat marker_para = new Mat();
marker_all.ConvertTo(marker_para, MatType.CV_8UC3);
Cv2.ImShow("分水岭的第二个参数", marker_para * 10000);
src.ConvertTo(src, MatType.CV_8UC3);
// 分水岭操作
Cv2.Watershed(src, marker_all);
Mat marker_para_end = new Mat();
marker_all.ConvertTo(marker_para_end, MatType.CV_8UC3);
Cv2.ImShow("分水岭函数 处理过 marker", marker_para_end * 10000);
// 生成随机颜色数组
Vec3b[] colors = new Vec3b[contours.Length];
Random rB = new Random();
Random rG = new Random();
Random rR = new Random();
for (int i = 0; i < contours.Length; i++)
{
var B = rB.Next(50, 98);
var G = rG.Next(47, 255);
var R = rR.Next(56, 120);
RNG rngB = new RNG((ulong)B);
RNG rngG = new RNG((ulong)G);
RNG rngR = new RNG((ulong)R);
//colors[i] = new Vec3b((byte)rngB.Uniform(0, 255), (byte)rngG.Uniform(0, 255), (byte)rngR.Uniform(0, 255));
//
colors[i] = new Vec3b((byte)0, (byte)0, (byte)255);
}
// 输出图像
Mat dest = Mat.Zeros(marker_all.Size(), MatType.CV_8UC3);
for (int i = 0; i < marker_all.Rows; i++)
{
for (int j = 0; j < marker_all.Cols; j++)
{
int index = marker_all.At<int>(i, j);
if (index > 0 && index <= contours.Length)
{
dest.At<Vec3b>(i, j) = colors[index - 1];
}
else
{
// 填充背景
dest.At<Vec3b>(i, j) = new Vec3b(255, 0, 0);
}
}
}
// 同原图相加
Cv2.Absdiff(src, dest, dest);
Cv2.ImShow("原图", src);
Cv2.ImShow("新图", dest);
}
}
}