Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct punct{
- Point p;
- int color;
- };
- void KMeansClustering_labo06_setOfPoints( const int K) {
- //obtain rgb image from original image
- Mat srcImg = imread("Images_Kmeans/points2.bmp", CV_LOAD_IMAGE_GRAYSCALE);
- Mat srcImgRgb(srcImg.size(), CV_8UC3);
- cvtColor(srcImg, srcImgRgb, CV_GRAY2RGB);
- const int height = srcImgRgb.rows;
- const int width = srcImgRgb.cols;
- //generate random colors
- std::default_random_engine gen;
- gen.seed(time(NULL));
- std::uniform_int_distribution<int> dist_img(0, 255);
- Vec3b *colors = (Vec3b*)malloc(K*sizeof(Vec3b));
- for (int i = 0; i < K; i++){
- colors[i] = { (uchar)dist_img(gen), (uchar)dist_img(gen), (uchar)dist_img(gen) };
- }
- //initialize k centers
- std::vector<Point> points;
- int pointsCounter = 0;
- for (int i = 0; i < height; i++){
- for (int j = 0; j < width; j++){
- if (srcImg.at<uchar>(i, j) == 0){
- Point newPoint(i, j);
- points.push_back(newPoint);
- pointsCounter++;
- }
- }
- }
- Point *m = (Point*)malloc(K*sizeof(Point));
- Point *m_new = (Point*)calloc(K,sizeof(Point));
- std::uniform_int_distribution<int> points_distribution(0, pointsCounter-1);
- for (int i = 0; i < K; i++){
- m[i] = points.at((int)points_distribution(gen));
- std::cout << m[i].x << " " << m[i].y << "\n";
- }
- float *distances = (float*)malloc(K*sizeof(float));
- punct *puncte = (punct*)malloc(pointsCounter*sizeof(punct));
- bool changed = true;
- while(changed) {
- //Assignment
- for (int i = 0; i < pointsCounter;i++){
- for (int k = 0; k < K; k++) {
- distances[k] = sqrt(((m[k].x - points[i].x) * (m[k].x - points[i].x)) + ((m[k].y - points[i].y) * (m[k].y - points[i].y)));
- }
- puncte[i].color = getMinimumElementIndex(distances, K);
- puncte[i].p = points.at(i);
- }
- //vectors used to update centers
- int*sumX = (int*)malloc(K*sizeof(int));
- int*sumY = (int*)malloc(K*sizeof(int));
- int*numerOfPoints = (int*)malloc(K*sizeof(int));
- for (int c = 0; c < K; c++){
- sumX[c] = 0;
- sumY[c] = 0;
- numerOfPoints[c] = 0;
- }
- //Update
- for (int i = 0; i < pointsCounter; i++){
- sumX[puncte[i].color] += puncte[i].p.x;
- sumY[puncte[i].color] += puncte[i].p.y;
- numerOfPoints[puncte[i].color]++;
- }
- for (int c = 0; c < K; c++) {
- m[c].x = sumX[c] / numerOfPoints[c];
- m[c].y = sumY[c] / numerOfPoints[c];
- }
- //check if assignment function produced new centers
- changed = false;
- for (int v = 0; v < K; v++){
- if (m[v].x != m_new[v].x || m[v].y != m_new[v].y){
- changed = true;
- }
- }
- for (int cnt = 0; cnt < K; cnt++){
- m_new[cnt] = m[cnt];
- }
- }
- Mat voronoi = srcImgRgb.clone();
- for (int i = 0; i < pointsCounter;i++){
- srcImgRgb.at<Vec3b>(puncte[i].p.x, puncte[i].p.y) = colors[puncte[i].color];
- }
- for (int i = 0; i < height; i++){
- for (int j = 0; j < width; j++){
- for (int k = 0; k < K; k++){
- distances[k] = sqrt(((m[k].x - i) * (m[k].x - i) + ((m[k].y - j) * (m[k].y - j))));
- }
- voronoi.at<Vec3b>(i, j) = colors[getMinimumElementIndex(distances,K)];
- }
- }
- imshow("result", srcImgRgb);
- imshow("voroni_mozaicare", voronoi);
- waitKey(0);
- }
- void KMeansClustering_lab06_RGB(int noOfIterations) {
- Mat srcImg = imread("images_Kmeans/img01.jpg", CV_LOAD_IMAGE_COLOR);
- const int height = srcImg.rows;
- const int width = srcImg.cols;
- Mat rez = Mat(height, width, CV_8UC3);
- //generate centers
- std::default_random_engine gen;
- std::uniform_int_distribution<int> dist_img(0, 255);
- const int K = 10;
- Vec3b m[K];
- for (int i = 0; i < K; i++) {
- m[i][0] = dist_img(gen);
- m[i][1] = dist_img(gen);
- m[i][2] = dist_img(gen);
- }
- Mat L = Mat(height, width, CV_8UC1);
- Mat newL = Mat(height, width, CV_8UC1);
- float distances[K];
- for (int count = 0; count < noOfIterations; count++) {
- //Assignment function
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < width; j++) {
- for (int k = 0; k < K; k++) {
- distances[k] = sqrt(
- ((m[k][0] - srcImg.at<Vec3b>(i, j)[0]) * (m[k][0] - srcImg.at<Vec3b>(i, j)[0])) +
- ((m[k][1] - srcImg.at<Vec3b>(i, j)[1]) * (m[k][1] - srcImg.at<Vec3b>(i, j)[1])) +
- ((m[k][2] - srcImg.at<Vec3b>(i, j)[2]) * (m[k][2] - srcImg.at<Vec3b>(i, j)[2]))
- );
- }
- L.at<uchar>(i, j) = getMinimumElementIndex(distances, K);
- }
- }
- if (count > 0) {
- //check if assignment function produced new results
- bool isEqual = (sum(L != newL) == Scalar(0, 0, 0));
- if (isEqual == true) {
- std::cout << "assignent function produced same results at iteration: " << count;
- break;
- }
- }
- //update centers
- int sumsR[K];
- int sumsG[K];
- int sumsB[K];
- int noOfPoints[K];
- for (int i = 0; i < K; i++) {
- sumsR[i] = 0;
- sumsG[i] = 0;
- sumsB[i] = 0;
- noOfPoints[i] = 0;
- }
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < width; j++) {
- sumsB[L.at<uchar>(i, j)] += srcImg.at<Vec3b>(i, j)[0];
- sumsG[L.at<uchar>(i, j)] += srcImg.at<Vec3b>(i, j)[1];
- sumsR[L.at<uchar>(i, j)] += srcImg.at<Vec3b>(i, j)[2];
- noOfPoints[L.at<uchar>(i, j)]++;
- }
- }
- for (int c = 0; c < K; c++) {
- if (noOfPoints[c] > 0) {
- m[c][0] = sumsB[c] / noOfPoints[c];
- m[c][1] = sumsG[c] / noOfPoints[c];
- m[c][2] = sumsR[c] / noOfPoints[c];
- }
- }
- L.copyTo(newL);
- }
- for (int i = 0; i < height; i++) {
- for (int j = 0; j < width; j++) {
- rez.at<Vec3b>(i, j) = m[L.at<uchar>(i, j)];
- }
- }
- imshow("color", rez);
- waitKey(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement