K-means 代碼

K-means 代碼。
將圖檔轉成黑白之後,分群。
K_GROUP = 設置的群組數量


#include<opencv2/opencv.hpp>
#include<iostream>
#include <cstdlib> /* 亂數相關函數 */
#include <ctime>   /* 時間相關函數 */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

using  namespace cv;
using namespace std;
#define K_GROUP 10
Mat srcImage, grayImage;
long long k_cnt = 0;
int max_x, min_x;
void K_Manes(Point *kp, int k_group);

int main()
{
	long timeStart, timeEnd; 
	timeStart = clock();
	char k_first_Flag = 0;
	Point K_center[K_GROUP];
	//unsigned long long k_min_data, k_max_data;
	//unsigned long long k_center[K_GROUP] = {0,0,0};

	srcImage = imread("D:\\download\\2.Result.bmp");
	//grayImage = imread("C:\\Users\\User\\Downloads\\Image2\\3.Left.bmp");
	cvtColor(srcImage, grayImage, CV_RGB2GRAY);


	//for (int x = 0; x < grayImage.rows; x++)
	//{
	//	for (int y = 0; y < grayImage.cols; y++)
	//	{
	//		if (grayImage.ptr<uchar>(x)[y] >= 180)
	//			grayImage.ptr<uchar>(x)[y] = 0;
	//		else if (grayImage.ptr<uchar>(x)[y] <= 20)
	//			grayImage.ptr<uchar>(x)[y] = 0;
	//	}
	//}

	//get point range
	for (int x = 0; x < grayImage.rows; x++)
	{
		for (int y = 0; y < grayImage.cols; y++)
		{
			if (grayImage.ptr<uchar>(x)[y] != 0)
						{
				if (k_first_Flag == 0)
				{
					k_first_Flag = 1;
					min_x = x;
				}
				max_x = x;
				k_cnt++;//get total point
			}
			//else if (grayImage.at<Vec3b>(x, y)[0] == 0 && grayImage.at<Vec3b>(x, y)[1] == 0 && grayImage.at<Vec3b>(x, y)[2] == 0)
			//{
				//grayImage.ptr<uchar>(x)[y] = 255;
			//	grayImage.at<Vec3b>(x, y)[0] = 255;//b
			//	grayImage.at<Vec3b>(x, y)[1] = 255;//g
			//	grayImage.at<Vec3b>(x, y)[2] = 255;//r
			//}
		}
	}

	//printf("min_x=%d\n", min_x);
	//printf("max_x=%d\n", max_x);

	//printf("k_min_data=%ld\n", k_min_data);
	//printf("k_max_data=%ld\n", k_max_data);

	//get rand point
	int lx, ly;
	srand(time(NULL));
	for (int i = 0; i < K_GROUP; i++)
	{
		lx = rand() % (max_x - min_x + 1) + min_x;
		//printf("lx=%d\n", lx);
		ly = (rand() % grayImage.cols) + 1;
		K_center[i].x = lx;
		K_center[i].y = ly;
		//printf("ly=%d\n", ly);
		//k_center[i] = lx*grayImage.rows + ly;
		//printf("k_center[%d]=%ld\n", i, k_center[i]);
	}


	//k_manes calculate
	K_Manes(K_center, K_GROUP);

	imshow("show",grayImage);

	timeEnd = clock();
	double times;
	times = (double)(timeEnd - timeStart) / 1000;
	printf("times=%f\n", times);
	waitKey();
	return 0;

}

void K_Manes(Point *kp, int k_group)
{
	Point p2;
	int d[K_GROUP];

	Point **data;
	unsigned long **dataD;
	unsigned long *loc_cnt;
	long loc_g = 0;
	//char rand_flag[K_GROUP];
	int lx, ly;
	int t = 100, stop_cnt = 0;
	Point last_p[K_GROUP];

	data = new Point*[K_GROUP]; 
	dataD = new unsigned long*[K_GROUP];
	loc_cnt = new unsigned long[K_GROUP];
	srand(time(NULL));

	for (int i = 0; i < K_GROUP; i++){
		data[i] = new Point[k_cnt];
		dataD[i] = new unsigned long[k_cnt];
		//rand_flag[i] = 0;
		last_p[i].x = 0;
		last_p[i].y = 0;
	}	

	for (int i = 0; i < K_GROUP; i++)
	{
		for (int j = 0; j < k_cnt; j++){
			data[i][j].x = 0;
			data[i][j].y = 0;
			dataD[i][j] = 0;
		}
	}

	//show point
	Mat show = Mat::zeros(grayImage.rows, grayImage.cols, grayImage.type());
	for (int x = 0; x < grayImage.rows; x++)
	{
		for (int y = 0; y < grayImage.cols; y++)
		{
			for (int i = 0; i < K_GROUP; i++)
				if (x == kp[i].x && y == kp[i].y){
					show.ptr<uchar>(x)[y] = 255;
					for (int j = 0; j < 10; j++){
						if (x - j > 0 && x + j < grayImage.rows && y + j < grayImage.cols && y - j>0){
							show.ptr<uchar>(x - j)[y] = 255;
							show.ptr<uchar>(x + j)[y] = 255;
							show.ptr<uchar>(x)[y - j] = 255;
							show.ptr<uchar>(x)[y + j] = 255;
						}
					}

				}

		}

	}
	//imshow("show point", show);
	
	while (t--)
	{
		//no any point and rand kp again
		//for (int i = 0; i < K_GROUP; i++)
		//{
		//	if (rand_flag[i])
		//	{
		//		lx = rand() % (max_x - min_x + 1) + min_x;
		//		//printf("lx=%d\n", lx);
		//		ly = (rand() % grayImage.cols) + 1;
		//		//printf("ly=%d\n", ly);
		//		kp[i].x = lx;
		//		kp[i].y = ly;
		//		rand_flag[i] = 0;
		//	}

		//}

		//clear loc_cnt
		for (int i = 0; i < K_GROUP; i++)
		{
			loc_cnt[i] = 0;
			for (int j = 0; j < k_cnt; j++)
			{
				data[i][j].x = 0;
				data[i][j].y = 0;
				dataD[i][j] = 0;
			}
		}

		int samll_d= 0;
		//find group
		for (int x = 0; x < grayImage.rows; x++)
		{
			for (int y = 0; y < grayImage.cols; y++)
			{
				if (grayImage.ptr<uchar>(x)[y] != 0)
				{
					p2.x = x;
					p2.y = y;
					//find distance
					loc_g = 0;
					samll_d = d[0];
					for (int i = 0; i < K_GROUP; i++)
					{
							
						d[i] = sqrt(pow(p2.x - kp[i].x, 2) + pow(p2.y - kp[i].y, 2));
						if (samll_d > d[i]){
							loc_g = i;
							samll_d = d[i];
							
						}

						//printf("d[%d]=%d  min value =%d  loc_g=%d \n", i, d[i], d[loc_g], loc_g);
					}

					//save data
					data[loc_g][loc_cnt[loc_g]].x = p2.x;
					data[loc_g][loc_cnt[loc_g]].y = p2.y;
					dataD[loc_g][loc_cnt[loc_g]] = samll_d;
					//printf("dataD[%d][%d] = %ld  ", loc_g, loc_cnt[loc_g], dataD[loc_g][loc_cnt[loc_g]]);

					loc_cnt[loc_g]++;
					data[loc_g][loc_cnt[loc_g]].x = 0;
					data[loc_g][loc_cnt[loc_g]].y = 0;
					dataD[loc_g][loc_cnt[loc_g]] = 0;
					//printf("loc_cnt[%d]=%d\n",loc_g ,loc_cnt[loc_g]);


				}

			}
		}



		//count max point
		int s = loc_cnt[0];
		int sl = 0;
		for (int i = 0; i < K_GROUP; i++){
			if (s < loc_cnt[i]){
				s = loc_cnt[i];
				sl = i;
				//printf("sl=%d\n", sl);
			}
		}

		//draw center point
		char p = 5;
		Mat show2 = Mat::zeros(show.rows, show.cols, show.type());
		for (int x = 0; x < show.rows; x++)
		{
			for (int y = 0; y < show.cols; y++)
			{
				for (int i = 0; i < K_GROUP; i++)
				{
					if (x == kp[i].x && y == kp[i].y){
						if (loc_cnt[i] > 1500){//0
							show2.ptr<uchar>(x)[y] = 255;
							i == sl ? p = 10 : p = 5;
							for (int j = 0; j < p; j++){
								if (x - j > 0 && x + j < grayImage.rows && y + j < grayImage.cols && y - j>0){
									show2.ptr<uchar>(x - j)[y] = 255;
									show2.ptr<uchar>(x + j)[y] = 255;
									show2.ptr<uchar>(x)[y - j] = 255;
									show2.ptr<uchar>(x)[y + j] = 255;
								}
							}
						}
						//printf("i=%d\n",i);
					}
				}

			}
		}


		//return loop 
		Mat show3 = Mat::zeros(show2.rows, show2.cols, show2.type());
		for (int i = 0; i < K_GROUP; i++)
		{
			if (stop_cnt > 3 || t == 0)
			{
				printf("t=%d\n", 100 - t);
				//for (int x = 0; x < K_GROUP; x++)
				//{
				//	for (int j = 0; j < loc_cnt[x]; j++)
				//	{
				//		//if (dataD[x][j] != 0)
				//		if (data[x][j].x != 0 && data[x][j].y != 0)
				//		{
				//			line(show3, Point(kp[x].y, kp[x].x), Point(data[x][j].y, data[x][j].x), Scalar(255, 255, 255));
				//		}

				//	}
				//}

				//for (int x = 0; x < grayImage.rows; x++)
				//{
				//	for (int y = 0; y < grayImage.cols; y++)
				//	{
				//		if (grayImage.ptr<uchar>(x)[y] != 0)
				//		{
				//			show2.ptr<uchar>(x)[y] = 255;
				//		}
				//	}
				//}

				for (int x = 0; x < K_GROUP; x++){
					//printf("loc_cnt[%d]=%ld\n", x, loc_cnt[x]);
					//printf("kp[%d].x=%d  kp[%d].y=%d \n", x, kp[x].x, x, kp[x].y);
				}
				imshow("show2 point", show2);
				//imshow("show3 point", show3);
				return;
			}

			if (last_p[i].x == kp[i].x && last_p[i].y == kp[i].y && loc_cnt[i]>0)
				stop_cnt++;
			else if (sqrt(pow(last_p[i].x - kp[i].x, 2) + pow(last_p[i].y - kp[i].y, 2))<5)
				stop_cnt++;

		}

		//calcuate K-group center again
		Point max_loc[K_GROUP], min_loc[K_GROUP];
		unsigned long long max_p, min_p;
		unsigned long long  new_point_X[K_GROUP];
		unsigned long long  new_point_Y[K_GROUP];
		for (int i = 0; i < K_GROUP; i++)
		{
			new_point_X[i] = 0;
			new_point_Y[i] = 0;
			max_p = dataD[i][0];
			min_p = dataD[i][0];
			max_loc[i].x = data[i][0].x;
			min_loc[i].y = data[i][0].y;

			for (int j = 0; j < loc_cnt[i]; j++)
			{
				if (data[i][j].x != 0 && data[i][j].y != 0)
				{

					if (loc_cnt[i] > 0){
						//get max & min point
						//if (min_p>dataD[i][j])
						//{
						//	min_p = dataD[i][j];
						//	min_loc[i].x = data[i][j].x;
						//	min_loc[i].y = data[i][j].y;
						//}

						//if (max_p < dataD[i][j])
						//{
						//	max_p = dataD[i][j];
						//	max_loc[i].x = data[i][j].x;
						//	max_loc[i].y = data[i][j].y;
						//}

						///average point
						new_point_X[i] += data[i][j].x;
						new_point_Y[i] += data[i][j].y;
					}
				}
			}

			//printf("new_point_X[%d]=%ld\n", i, new_point_X[i]);
			//printf("new_point_Y[%d]=%ld\n", i, new_point_Y[i]);

		}
		//update group center
		for (int i = 0; i < K_GROUP; i++)
		{
			if (loc_cnt[i] > 0){
				//max point & min point average
				//new_point_X[i] = (min_loc[i].x + max_loc[i].x) / 2;
				//new_point_Y[i] = (min_loc[i].y + max_loc[i].y) / 2;

				//average point
				new_point_X[i] /= loc_cnt[i];
				new_point_Y[i] /= loc_cnt[i];

				last_p[i].x = kp[i].x;
				last_p[i].y = kp[i].y;

				kp[i].x = new_point_X[i];
				kp[i].y = new_point_Y[i];
				//printf("kp[%d].x=%d  kp[%d].y=%d \n", i, kp[i].x, i, kp[i].y);
			}
			//else{
			//	rand_flag[i] = 1;
			//	//printf("2 kp[%d].x=%d  kp[%d].y=%d \n", i, kp[i].x, i, kp[i].y);
			//}


			//printf("loc_cnt[%d]=%ld\n", i, loc_cnt[i]);
			//printf("new_point_X[%d]=%ld\n", i, new_point_X[i]);
			//printf("new_point_Y[%d]=%ld\n", i, new_point_Y[i]);
		}

	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值