using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OpenCvSharp;
namespace OpenCVTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
T1();
}
private void T1()
{
Mat dst = new Mat();
Mat src = Cv2.ImRead("C:\\Pictures\\a.jpg", ImreadModes.Color);
Mat dst_Image = MyFindContours(src);
Cv2.ImShow("srcImage:", src);
Cv2.ImShow("contours", dst_Image);
Mat data = mat_to_samples(src);
int numCluster = 4;
Mat labels = new Mat();
var centers = new Mat();
TermCriteria criteria = new TermCriteria(CriteriaTypes.Eps, 10, 0.1); // TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1);
// kmeans(data, numCluster, labels, criteria, 3, KMEANS_PP_CENTERS);
Cv2.Kmeans(data, numCluster, labels, criteria, 3, KMeansFlags.PpCenters, centers);
//https://github.com/VahidN/OpenCVSharp-Samples/blob/master/OpenCVSharpSample11/Program.cs
// 3.背景与人物二值化
Mat mask = Mat.Zeros(src.Size(), MatType.CV_8UC1);
int index = src.Rows * 2 + 2; //获取点(2,2)作为背景色
int cindex = labels.At<int>(index, 0);
src.CopyTo(dst);
/* 提取背景特征 */
for (int row = 0; row < src.Rows; row++)
{
for (int col = 0; col < src.Cols; col++)
{
index = row * src.Cols + col;
int label = labels.At<int>(index, 0);
if (label == cindex)
{ // 背景
mask.At<byte>(row, col) = 0;
}
else
{
mask.At<byte>(row, col) = 255;
}
}
}
Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3), new Point(-1, -1));
Cv2.Erode(mask, mask, kernel);
Cv2.GaussianBlur(mask, mask, new Size(3, 3), 0, 0);
RNG rng = new RNG();
Vec3b color = new Vec3b();
color[0] = (byte)rng.Uniform(0, 255);
color[2] = (byte)rng.Uniform(0, 255);
color[1] = (byte)rng.Uniform(0, 255);
dst = Mat.Zeros(src.Size(), src.Type());
for (int row = 0; row < src.Rows; row++)
{
for (int col = 0; col < src.Cols; col++)
{
int temp = mask.At<byte>(row, col);//(row,col)的像素值
if (temp == 255)//在mask为白色的区域,将src直接赋给dst
{
dst.At<Vec3b>(row, col) = src.At<Vec3b>(row, col);//前景
}
else if (temp == 0) //在mask为黑色的区域,给dst添上随机颜色
{
dst.At<Vec3b>(row, col) = color; //背景
}
else//边缘处:非纯黑/非纯白
{
double weight = temp / 255;//权重值(可以理解为灰度占比)
//在(row,col)上src的rgb值
int b_src = src.At<Vec3b>(row, col)[0];
int g_src = src.At<Vec3b>(row, col)[1];
int r_src = src.At<Vec3b>(row, col)[2];
//在(row,col)上color的rgb随机值
int b_color = color[0];
int g_color = color[1];
int r_color = color[2];
//按权重weight通道混合
dst.At<Vec3b>(row, col)[0] = (byte)(weight * b_src + (1 - weight) * b_color);
dst.At<Vec3b>(row, col)[1] = (byte)(weight * g_src + (1 - weight) * g_color);
dst.At<Vec3b>(row, col)[2] = (byte)(weight * r_src + (1 - weight) * r_color);
}
}
Cv2.ImShow("mask", mask);
using (new Window("dst image", dst))
{
Cv2.WaitKey();
}
}
}
Mat mat_to_samples(Mat image)
{
int width = image.Cols;
int height = image.Rows;
int samplecount = width * height;//采样数
int dims = image.Channels();
Mat temp = new Mat(samplecount, dims, MatType.CV_32FC1, new Scalar(10));// (samplecount, dims, CV_32F, Scalar(10));//存放样本点
// RGB 数据转换到样本数据
int index = 0;
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
index = row * width + col;//索引值 = 行*宽度 + 列
Vec3b bgr = image.At<Vec3b>(row, col);
temp.At<float>(index, 0) = Convert.ToInt32(bgr[0]);
temp.At<float>(index, 1) = Convert.ToInt32(bgr[1]);
temp.At<float>(index, 2) = Convert.ToInt32(bgr[2]);
}
}
return temp;
}
// findContours()用于对物体轮廓进行检测
Mat MyFindContours(Mat srcImage)
{
//转化为灰度图
Mat src_gray = new Mat();
Cv2.CvtColor(srcImage, src_gray, ColorConversionCodes.RGB2GRAY);
//滤波
Cv2.Blur(src_gray, src_gray, new Size(3, 3));
//Canny边缘检测
Mat canny_Image = new Mat();
Cv2.Canny(src_gray, canny_Image, 100, 200);
//获得轮廓
Point[][] contours;
HierarchyIndex[] hierarchly;
Cv2.FindContours(canny_Image, out contours, out hierarchly, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple, new Point(0, 0));
//将结果画出并返回结果
Mat dst_Image = Mat.Zeros(canny_Image.Size(), srcImage.Type());
Random rnd = new Random();
for (int i = 0; i < contours.Length; i++)
{
Scalar color = new Scalar(rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255));
Cv2.DrawContours(dst_Image, contours, i, color, 2, LineTypes.Link8, hierarchly);
}
return dst_Image;
}
void Test1()
{
Mat src = new Mat("C:\\Pictures\\a.jpg", ImreadModes.Grayscale);
// Mat src = Cv2.ImRead("lenna.png", ImreadModes.GrayScale);
Mat dst = new Mat();
Cv2.Canny(src, dst, 50, 200);
using (new Window("src image", src))
using (new Window("dst image", dst))
{
Cv2.WaitKey();
}
}
}
}