K-means和EM算法

时间:2015-06-02 21:19:24

标签: c++ opencv cluster-analysis k-means image-segmentation

如何实施k-means& EM算法没有调用openCV函数来进行图像分割?

我从这段代码开始:

#include opencv2/highgui/highgui.hpp
#include iostream

using namespace cv;
using namespace std;

int main()
{
    Mat img = imread("testImage.png", 0);
    Mat label_img;
    label_img.create(img.cols, img.rows, CV_8UC1);
}

我该如何继续?

2 个答案:

答案 0 :(得分:0)

K-means非常简单地通过迭代两步直到收敛,E步和M步。

初始化:

将每个像素随机分配给k个群集中的一个。也就是说,对于label_img中的每个条目,随机选择一个数字[0..k-1]

期望(E-step)

如果将像素分配给聚类(label_img),则可以计算每个聚类的中心(只是分配给该聚类的像素值的平均值)。
在此阶段结束时,您将k个向量指向k群集的中心。

最大化(M步)

拥有k个群集后,您可以计算每个像素到k个中心的距离,并将其(通过将label_img中的相应条目更改)分配到距离最近的中心像素。
在此阶段结束时,您将为每个像素分配一个新的分配(label_img的新值)

您需要重复这两个步骤,直到label_img不再发生更改或超过预定义的迭代次数。

答案 1 :(得分:0)

include <opencv2/highgui/highgui.hpp>
include <iostream>

using namespace cv;
using namespace std;

void kmeans(const Mat frame, Mat label) {
}

void em(const Mat frame, const Mat label, Mat new_label) {
}

void main()
{
Mat frame;
Mat label_img;
Mat em_label;

frame = imread("testImage.png", 0);

kmeans(frame, label_img);

em(frame, label_img, em_label);
label_img.create(frame.cols, frame.rows, CV_8UC1);

label_img.ptr<float>(25)[30] = 0;
label_img.ptr<float>(25)[31] = 255;

}