??
[函数名称]
??图像KMeans聚类??????KMeansCluster(WriteableBitmap?src,int?k)
/// <summary> /// KMeans Cluster process. /// </summary> /// <param name="src">The source image.</param> /// <param name="k">Cluster threshould, from 2 to 255.</param> /// <returns></returns> public static WriteableBitmap KMeansCluster(WriteableBitmap src,int k)////KMeansCluster { if (src != null) { int w = src.PixelWidth; int h = src.PixelHeight; WriteableBitmap dstImage = new WriteableBitmap(w, h); byte[] temp = src.PixelBuffer.ToArray(); byte[] tempMask = (byte[])temp.Clone(); int b = 0, g = 0, r = 0; //定义灰度图像信息存储变量 byte[] imageData = new byte[w * h]; //定义聚类均值存储变量(存储每一个聚类的均值) double[] meanCluster = new double[k]; //定义聚类标记变量(标记当前像素属于哪一类) int[] markCluster = new int[w * h]; //定义聚类像素和存储变量(存储每一类像素值之和) double[] sumCluster = new double[k]; //定义聚类像素统计变量(存储每一类像素的数目) int []countCluster = new int[k]; //定义聚类RGB分量存储变量(存储每一类的RGB三分量大小) int[] sumR = new int[k]; int[] sumG = new int[k]; int[] sumB = new int[k]; //临时变量 int sum = 0; //循环控制变量 bool s = true; double[] mJduge = new double[k]; double tempV = 0; int cou = 0; //获取灰度图像信息 for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { b = tempMask[i * 4 + j * w * 4]; g = tempMask[i * 4 + 1 + j * w * 4]; r = tempMask[i * 4 + 2 + j * w * 4]; imageData[i + j * w] = (byte)(b * 0.114 + g * 0.587 + r * 0.299); } } while (s) { sum = 0; //初始化聚类均值 for (int i = 0; i < k; i++) { meanCluster[i] = i * 255.0 / (k - 1); } //计算聚类归属 for (int i = 0; i < imageData.Length; i++) { tempV = Math.Abs((double)imageData[i] - meanCluster[0]); cou = 0; for (int j = 1; j < k; j++) { double t = Math.Abs((double)imageData[i] - meanCluster[j]); if (tempV > t) { tempV = t; cou = j; } } countCluster[cou]++; sumCluster[cou] += (double)imageData[i]; markCluster[i] = cou; } //更新聚类均值 for (int i = 0; i < k; i++) { meanCluster[i] = sumCluster[i] / (double)countCluster[i]; sum += (int)(meanCluster[i] - mJduge[i]); mJduge[i] = meanCluster[i]; } if (sum == 0) { s = false; } } //计算聚类RGB分量 for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { sumB[markCluster[i + j * w]] += tempMask[i * 4 + j * w * 4]; sumG[markCluster[i + j * w]] += tempMask[i * 4 + 1 + j * w * 4]; sumR[markCluster[i + j * w]] += tempMask[i * 4 + 2 + j * w * 4]; } } for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { temp[i * 4 + j * 4 * w] = (byte)(sumB[markCluster[i + j * w]] / countCluster[markCluster[i + j * w]]); temp[i * 4 + 1 + j * 4 * w] = (byte)(sumG[markCluster[i + j * w]] / countCluster[markCluster[i + j * w]]); temp[i * 4 + 2 + j * 4 * w] = (byte)(sumR[markCluster[i + j * w]] / countCluster[markCluster[i + j * w]]); } } Stream sTemp = dstImage.PixelBuffer.AsStream(); sTemp.Seek(0, SeekOrigin.Begin); sTemp.Write(temp, 0, w * 4 * h); return dstImage; } else { return null; } }