K-means and EM algorithms

K-means and EM algorithms

本文关键字:algorithms EM and K-means      更新时间:2023-10-16

如何实现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);
}

K-means通过迭代e步和m步直到收敛非常简单。

初始化:

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

期望(E-step)

给定一个分配给集群的像素(label_img),您可以计算每个集群的中心(简单地说就是分配给该集群的像素值的平均值)。
在此阶段结束时,您将拥有指向k集群中心的k向量。

最大化(M-step)

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

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

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