현실감각 0% :: 현실감각 0%

소스예제 퍼온거 2013. 7. 2. 18:08

opencvsharp을 이용한 Kmeans 구현



출처 : http://coderepos.org/share/browser/lang/cpluspluscli/OpenCvSharp2/trunk/OpenCvSharp.Test/Samples/KMeans.cs?rev=31328


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];
        }
    }
}