Opencv之kmeans图像分割

int imageSeg_kmeans()
{
	string image_path = "D:/vs2019Proj/ConsoleApplication1/timg.jpg";
	Mat src_image = imread(image_path);
	if (!src_image.data)
	{
		cout << "could not load image.." << endl;
		return -1;
	}
	//颜色板
	vector colorTab = {
		{0,0,255},
		{0,255,0},
		{255,0,0},
		{255,255,0},
		{0,255,255},
		{255,0,255}
	};
	int width = src_image.cols;
	int height = src_image.rows;
	int chnes = src_image.channels();
	//把彩色图像中的数据点提取出来放入points里面
	//points的类型是CV_32F
	Mat points(width * height, chnes, CV_32F,Scalar(10));
	for (int row = 0; row < height; row++)
	{
		uchar* ptr = src_image.ptr(row);
		for (int col = 0; col < width* chnes; col+= chnes)
		{
			int index = row * width + col/chnes;
			float* ptr_points = points.ptr(index);
			ptr_points[0] = static_cast(ptr[col]);//B
			ptr_points[1] = static_cast(ptr[col+1]);//G
			ptr_points[2] = static_cast(ptr[col+2]);//R
		}
	}
	//设置kmeans的参数,执行kmeans
	//clusters 表示要把图像分割为几类
	int clusters = 2;
	//attempts 表示要在图像上尝试几次kmeans计算,因为可能会存在起始点选择不太好的情况,所以要多尝试几次
	int attempts = 3;
	//flags 表示选取中心点的方法,clusters为几就要选取多少个中心点
	int flags = cv::KMEANS_PP_CENTERS;
	//centers 记录迭代完成后中心点的位置
	Mat centers(clusters, 1, points.type());
	//label 记录每一个像素点所属的类别
	Mat label;
	//critreia kmeans算法的终止条件
	//TermCriteria::EPS 迭代算法停止时要达到的精度
	//TermCriteria::COUNT 表示最大迭代次数
	TermCriteria critreia = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1);
	kmeans(points, clusters, label, critreia, attempts, flags, centers);
	//处理kmeans的结果,即处理label,并且还原为分割图像
	//label数据结构是width*height行,1列,每一行表示一个像素点的类别
	Mat result = Mat::zeros(src_image.size(), src_image.type());
	for (int row = 0; row < height; row++)
	{
		uchar* ptr = result.ptr(row);
		for (int col = 0; col < width*3; col+=3)
		{
			int index = label.at(row * width + col / 3, 0);
			ptr[col] = colorTab[index][0];
			ptr[col + 1] = colorTab[index][1];
			ptr[col + 2] = colorTab[index][2];
		}
	}
	//输出每一种分割类别的中心点
	for (int i = 0; i < centers.rows; i++)
	{
		int x = centers.at(i, 0);
		int y = centers.at(i, 1);
		cout << "center " << i << ":" << x << " " << y << endl;
	}
	imshow("result", result);
	imshow("srcimage", src_image);
}

 

你可能感兴趣的:(图像分割,opencv,opencv)