K-means 代碼

    科技2024-07-21  66

    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]); } } }
    Processed: 0.012, SQL: 8