소스예제 퍼온거
2013. 7. 2. 18:08
opencvsharp을 이용한 Kmeans 구현
int MAX_CLUSTERS = 10; int size = srcImg.Width * srcImg.Height; using (CvMat color = Cv.CreateMat(MAX_CLUSTERS, 1, MatrixType.F32C3)) using (CvMat count = Cv.CreateMat(MAX_CLUSTERS, 1, MatrixType.S32C1)) using (CvMat clusters = Cv.CreateMat(size, 1, MatrixType.S32C1)) using (CvMat points = Cv.CreateMat(size, 1, MatrixType.F32C3)) { unsafe { float* p_mat = (float*)points.Data; // 行列の要素へのポインタ byte* p_img = (byte*)srcImg.ImageData; // 画像の画素へのポインタ for (int i = 0; i < size; i++) { p_mat[i * 3 + 0] = p_img[i * 3 + 0]; p_mat[i * 3 + 1] = p_img[i * 3 + 1]; p_mat[i * 3 + 2] = p_img[i * 3 + 2]; } } Cv.KMeans2(points, MAX_CLUSTERS, clusters, new CvTermCriteria(10, 1.0)); Cv.SetZero(color); Cv.SetZero(count); unsafe { int* p_clu = clusters.DataInt32; // cluster の要素へのポインタ int* p_cnt = count.DataInt32; // count の要素へのポインタ float* p_clr = color.DataSingle; // color の要素へのポインタ float* p_pnt = points.DataSingle; // points の要素へのポインタ for (int i = 0; i < size; i++) { int idx = p_clu[i]; // clusters->data.i[i] int j = ++p_cnt[idx]; // ++count->data.i[idx]; p_clr[idx * 3 + 0] = p_clr[idx * 3 + 0] * (j - 1) / j + p_pnt[i * 3 + 0] / j; p_clr[idx * 3 + 1] = p_clr[idx * 3 + 1] * (j - 1) / j + p_pnt[i * 3 + 1] / j; p_clr[idx * 3 + 2] = p_clr[idx * 3 + 2] * (j - 1) / j + p_pnt[i * 3 + 2] / j; } } unsafe { int* p_clu = clusters.DataInt32; // cluster の要素へのポインタ float* p_clr = color.DataSingle; // color の要素へのポインタ byte* p_dst = (byte*)dstImg.ImageData; // dst の画素へのポインタ for (int i = 0; i < size; i++) { int idx = p_clu[i]; p_dst[i * 3 + 0] = (byte)p_clr[idx * 3 + 0]; p_dst[i * 3 + 1] = (byte)p_clr[idx * 3 + 1]; p_dst[i * 3 + 2] = (byte)p_clr[idx * 3 + 2]; } } }