Safiron

K-means

Feb 25th, 2017
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.45 KB | None | 0 0
  1. // K-MEAN
  2. #include "Task7.hpp"
  3. //________________________________________indexing
  4. void Task7::Index_f(Mat G, Mat Index, int y, int x, int idx)
  5. {
  6.    
  7.     if (Index.at<uchar>(y, x) == 0 && (G.at<uchar>(y, x) == 255))
  8.     {
  9.         Index.at<uchar>(y, x) = idx;
  10.        
  11.         Index_f(G, Index, y + 1, x, idx);
  12.         Index_f(G, Index, y - 1, x, idx);
  13.         Index_f(G, Index, y, x + 1, idx);
  14.         Index_f(G, Index, y, x - 1, idx);
  15.         Index_f(G, Index, y - 1, x - 1, idx);
  16.         Index_f(G, Index, y + 1, x - 1, idx);
  17.         Index_f(G, Index, y - 1, x + 1, idx);
  18.         Index_f(G, Index, y + 1, x + 1, idx);
  19.        
  20.     }
  21.    
  22.     return;
  23.    
  24. }
  25.  
  26. int Task7::Moment(Mat Index, Mat Cont, int idx, int p, int q)
  27. {
  28.    
  29.     int sum_m = 0;
  30.    
  31.     for (int y = 0; y < Index.rows; y++)
  32.     {
  33.         for (int x = 0; x < Index.cols; x++)
  34.         {
  35.            
  36.             if (Index.at<uchar>(y, x) == idx)
  37.             {
  38.                 Cont.at<uchar>(y, x) = 1;
  39.                 sum_m = sum_m + (pow(x, p)*pow(y, q));
  40.             }
  41.         }
  42.     }
  43.    
  44.     return sum_m;
  45.    
  46. }
  47.  
  48. float Task7::Centmoment(Mat Index, Mat Cont, int idx, int p, int q, float xT, float yT)
  49. {
  50.    
  51.     int sum_p = 0;
  52.    
  53.     for (int y = 1; y < Index.rows - 1; y++)
  54.     {
  55.         for (int x = 1; x < Index.cols - 1; x++)
  56.         {
  57.             if (Index.at<uchar>(y, x) == idx)
  58.             {
  59.                 sum_p = sum_p + (pow((x - xT), p)*pow((y - yT), q));
  60.             }
  61.         }
  62.     }
  63.    
  64.     return sum_p;
  65.    
  66. }
  67.  
  68. int Task7::Perimm(Mat Index, int idx)
  69. {
  70.    
  71.     int perimeter = 0;
  72.    
  73.     for (int y = 0; y < Index.rows; y++)
  74.     {
  75.         for (int x = 0; x < Index.cols; x++)
  76.         {
  77.            
  78.             if (Index.at<uchar>(y, x) == idx)
  79.             {
  80.                 if ((Index.at<uchar>(y, x - 1) != idx) || (Index.at<uchar>(y, x + 1) != idx) || (Index.at<uchar>(y - 1, x) != idx) || (Index.at<uchar>(y + 1, x) != idx))
  81.                 {
  82.                     perimeter++;
  83.                 }
  84.             }
  85.         }
  86.     }
  87.    
  88.     return perimeter;
  89.    
  90. }
  91.  
  92. Mat Task7::Erase(Mat Cont)
  93. {
  94.    
  95.     for (int y = 0; y < Cont.rows; y++)
  96.     {
  97.         for (int x = 0; x < Cont.cols; x++)
  98.         {
  99.             Cont.at<uchar>(y, x) = 0;
  100.         }
  101.     }
  102.    
  103.     return Cont;
  104.    
  105. }
  106.  
  107. Task7::Task7()
  108. {
  109.     cv::Mat src_img;
  110.    
  111.    
  112.     src_img = cv::imread("train.png", 0);
  113.    
  114.     if (!src_img.data)
  115.     {
  116.         printf("No image loaded.\n");
  117.         return;
  118.     }
  119.    
  120.     cv::Mat g_img(src_img.rows, src_img.cols, CV_8U);
  121.     cv::Mat index(src_img.rows, src_img.cols, CV_8U);
  122.     cv::Mat cont(src_img.rows, src_img.cols, CV_8U);
  123.    
  124.    
  125.     uchar t = 128;
  126.    
  127.     //________________________________________tresholding
  128.    
  129.     for (int y = 0; y < src_img.rows; y++)
  130.     {
  131.         for (int x = 0; x < src_img.cols; x++)
  132.         {
  133.             if (src_img.at<uchar>(y, x) > t)
  134.             {
  135.                 g_img.at<uchar>(y, x) = 255;
  136.             }
  137.             else if (src_img.at<uchar>(y, x) <= t)
  138.             {
  139.                 g_img.at<uchar>(y, x) = 0;
  140.             }
  141.         }
  142.     }
  143.    
  144.     index = Erase(index);
  145.     cont = Erase(cont);
  146.    
  147.     int idx = 25;
  148.     int count = 0;
  149.    
  150.     for (int y = 0; y < src_img.rows; y++)
  151.     {
  152.         for (int x = 0; x < src_img.cols; x++)
  153.         {
  154.             if ((g_img.at<uchar>(y, x) == 255) && (index.at<uchar>(y, x) == 0))
  155.             {
  156.                 Index_f(g_img, index, y, x, idx);
  157.                 idx += 15;
  158.                 count++;
  159.             }
  160.            
  161.         }
  162.     }
  163.    
  164.     printf("\n\nPocet detekovanych objektu %d\n", count);
  165.    
  166.     //float eth_F1[3] = { 0.0, 0.0, 0.0 };
  167.     //float eth_F2[3] = { 0.0, 0.0, 0.0 };
  168.    
  169.    
  170.     int* m10 = NULL;
  171.     int* m01 = NULL;
  172.     float* x_T = NULL;
  173.     float* y_T = NULL;
  174.     float* my02 = NULL;
  175.     float* my20 = NULL;
  176.     float* my00 = NULL;
  177.     float* my11 = NULL;
  178.     int* perimeter = NULL;
  179.     float* F1 = NULL;
  180.     float* F2 = NULL;
  181.     int* type = NULL;
  182.     int* Type = NULL;
  183.     m10 = new int[count];
  184.     m01 = new int[count];
  185.     x_T = new float[count];
  186.     y_T = new float[count];
  187.     my02 = new float[count];
  188.     my20 = new float[count];
  189.     my11 = new float[count];
  190.     my00 = new float[count];
  191.     perimeter = new int[count];
  192.     F1 = new float[count];
  193.     F2 = new float[count];
  194.     type = new int[count];
  195.     Type = new int[count];
  196.    
  197.    
  198.     for (int j = 0; j < count; j++){
  199.         m10[j] = 0;
  200.         m01[j] = 0;
  201.         x_T[j] = 0.0;
  202.         y_T[j] = 0.0;
  203.         my02[j] = 0.0;
  204.         my20[j] = 0.0;
  205.         my11[j] = 0.0;
  206.         my00[j] = 0.0;
  207.         perimeter[j] = 0;
  208.         F1[j] = 0.0;
  209.         F2[j] = 0.0;
  210.     }
  211.    
  212.     int i = 0;
  213.    
  214.    
  215.     for (int y = 0; y < index.rows; y++)
  216.     {
  217.         for (int x = 0; x < index.cols; x++)
  218.         {
  219.             if (index.at<uchar>(y, x) != 0 && cont.at<uchar>(y, x) == 0)
  220.             {
  221.                 int area;
  222.                 float my_min = 0.0;
  223.                 float my_max = 0.0;
  224.                 area = Moment(index, cont, index.at<uchar>(y, x), 0, 0);
  225.                 //printf("Area of the object %d is %d\n",i+1, area);
  226.                 m10[i] = Moment(index, cont, index.at<uchar>(y, x), 1, 0);
  227.                 m01[i] = Moment(index, cont, index.at<uchar>(y, x), 0, 1);
  228.                 x_T[i] = (float)m10[i] / (float)area;
  229.                 y_T[i] = (float)m01[i] / (float)area;
  230.                 //printf("\nThe center of object %d is in [%f, %f]\n", i + 1, x_T[i], y_T[i]);
  231.                 my20[i] = Centmoment(index, cont, index.at<uchar>(y, x), 2, 0, x_T[i], y_T[i]);
  232.                 my02[i] = Centmoment(index, cont, index.at<uchar>(y, x), 0, 2, x_T[i], y_T[i]);
  233.                 my11[i] = Centmoment(index, cont, index.at<uchar>(y, x), 1, 1, x_T[i], y_T[i]);
  234.                 my00[i] = Centmoment(index, cont, index.at<uchar>(y, x), 0, 0, x_T[i], y_T[i]);
  235.                 perimeter[i] = Perimm(index, index.at<uchar>(y, x));
  236.                 //printf("The perimeter of an object %d  is %d \n",i+1, perimeter[i]);
  237.                 //printf("Area of the object %d is my00 = %f\n", i + 1, my00[i]);
  238.                 F1[i] = pow(perimeter[i], 2) / (100 * my00[i]);
  239.                 my_max = ((my20[i] + my02[i]) / 2) + ((sqrtf(abs((4 * my11[i]) + powf((my20[i] - my02[i]), 2)))) / 2);
  240.                 my_min = ((my20[i] + my02[i]) / 2) - ((sqrtf(abs((4 * my11[i]) + powf((my20[i] - my02[i]), 2)))) / 2);
  241.                 //printf(" my20 = %f, my02 = %f, my11 = %f, my00 = %f, my_min = %f and my_max =  %f \n", my20[i], my02[i], my11[i], my00[i], my_min, my_max);
  242.                 F2[i] = my_min / my_max;
  243.                 //printf("The features of an object %d are F1 = %f and F2 =  %f\n", i + 1, F1[i], F2[i]);
  244.                 i++;
  245.             }
  246.         }
  247.     }
  248.    
  249.    
  250.    
  251.    
  252.     //K-MEANS
  253.     float centr_1[3] = { 0.0, 0.1, 0.2 };
  254.     float centr_2[3] = { 0.85, 0.8, 0.5 };
  255.     float old_centr_1[3] = { 0.0, 0.0, 0.0 };
  256.     float old_centr_2[3] = { 0.0, 0.0, 0.0 };
  257.    
  258.    
  259.     float* one_1 = NULL;
  260.     one_1 = new float[count];
  261.     float* two_1 = NULL;
  262.     two_1 = new float[count];
  263.     float* three_1 = NULL;
  264.     three_1 = new float[count];
  265.     float* one_2 = NULL;
  266.     one_2 = new float[count];
  267.     float* two_2 = NULL;
  268.     two_2 = new float[count];
  269.     float* three_2 = NULL;
  270.     three_2 = new float[count];
  271.    
  272.     for (int k = 0; k < 10; k++)
  273.     {
  274.        
  275.         int Counter[3] = { 0, 0, 0 };
  276.         float Suma_1[3] = { 0.0, 0.0, 0.0 };
  277.         float Suma_2[3] = { 0.0, 0.0, 0.0 };
  278.        
  279.        
  280.         for (int j = 0; j < count; j++)
  281.         {
  282.             one_1[j] = 0.0;
  283.             one_2[j] = 0.0;
  284.             two_1[j] = 0.0;
  285.             two_2[j] = 0.0;
  286.             three_1[j] = 0.0;
  287.             three_2[j] = 0.0;
  288.            
  289.             float dist_1 = sqrtf(pow((F1[j] - centr_1[0]), 2) + pow((F2[j] - centr_2[0]), 2));
  290.             float dist_2 = sqrtf(pow((F1[j] - centr_1[1]), 2) + pow((F2[j] - centr_2[1]), 2));
  291.             float dist_3 = sqrtf(pow((F1[j] - centr_1[2]), 2) + pow((F2[j] - centr_2[2]), 2));
  292.            
  293.            
  294.             if ((dist_1 < dist_2) && (dist_1 < dist_3))
  295.             {
  296.                 Type[j] = 1;
  297.             }
  298.             else if ((dist_2 < dist_1) && (dist_2 < dist_3))
  299.             {
  300.                 Type[j] = 2;
  301.             }
  302.             else if ((dist_3 < dist_1) && (dist_3 < dist_2))
  303.             {
  304.                 Type[j] = 3;
  305.             }
  306.             switch (Type[j])
  307.             {
  308.                 case 1:
  309.                     one_1[j] = F1[j];
  310.                     one_2[j] = F2[j];
  311.                     break;
  312.                 case 2:
  313.                     two_1[j] = F1[j];
  314.                     two_2[j] = F2[j];
  315.                     break;
  316.                 case 3:
  317.                     three_1[j] = F1[j];
  318.                     three_2[j] = F2[j];
  319.                     break;
  320.             }
  321.         }
  322.         for (int j = 0; j < count; j++)
  323.         {
  324.             if ((one_1[j] != 0.0) || (one_2[j] != 0.0))
  325.             {
  326.                 Counter[0] = Counter[0] + 1;
  327.                 Suma_1[0] = Suma_1[0] + one_1[j];
  328.                 Suma_2[0] = Suma_2[0] + one_2[j];
  329.             }
  330.             else if ((two_1[j] != 0.0) || (two_2[j] != 0.0))
  331.             {
  332.                 Counter[1] = Counter[1] + 1;
  333.                 Suma_1[1] = Suma_1[1] + two_1[j];
  334.                 Suma_2[1] = Suma_2[1] + two_2[j];
  335.             }
  336.             else if ((three_1[j] != 0.0) || (three_2[j] != 0.0))
  337.             {
  338.                 Counter[2] = Counter[2] + 1;
  339.                 Suma_1[2] = Suma_1[2] + three_1[j];
  340.                 Suma_2[2] = Suma_2[2] + three_2[j];
  341.             }
  342.         }
  343.         old_centr_1[0] = centr_1[0];
  344.         old_centr_1[1] = centr_1[1];
  345.         old_centr_1[2] = centr_1[2];
  346.         old_centr_2[0] = centr_2[0];
  347.         old_centr_2[1] = centr_2[1];
  348.         old_centr_2[2] = centr_2[2];
  349.        
  350.         centr_1[0] = Suma_1[0] / (float)Counter[0];
  351.         centr_1[1] = Suma_1[1] / (float)Counter[1];
  352.         centr_1[2] = Suma_1[2] / (float)Counter[2];
  353.         centr_2[0] = Suma_2[0] / (float)Counter[0];
  354.         centr_2[1] = Suma_2[1] / (float)Counter[1];
  355.         centr_2[2] = Suma_2[2] / (float)Counter[2];
  356.         float differ_0 = sqrtf(pow((old_centr_1[0] - centr_1[0]), 2) + pow((old_centr_2[0] - centr_2[0]), 2));
  357.         float differ_1 = sqrtf(pow((old_centr_1[1] - centr_1[1]), 2) + pow((old_centr_2[1] - centr_2[1]), 2));
  358.         float differ_2 = sqrtf(pow((old_centr_1[2] - centr_1[2]), 2) + pow((old_centr_2[2] - centr_2[2]), 2));
  359.         if ((differ_0 < 0.0001) && (differ_1 < 0.0001) && (differ_2 < 0.0001))
  360.         {
  361.             goto end;
  362.         }
  363.         printf("\n\nThe Centroid_1 = %f and %f and %f\n", centr_1[0], centr_1[1], centr_1[2]);
  364.         printf("The Centroid_2 = %f and %f and %f\n\n", centr_2[0], centr_2[1], centr_2[2]);
  365.     }
  366.    
  367. end:
  368.    
  369.    
  370.     //Detekce objektų pomoci K-MEANS
  371.     for (int j = 0; j < count; j++)
  372.     {
  373.         float vzdal_1 = sqrtf(pow((F1[j] - centr_1[0]), 2) + pow((F2[j] - centr_2[0]), 2));
  374.         float vzdal_2 = sqrtf(pow((F1[j] - centr_1[1]), 2) + pow((F2[j] - centr_2[1]), 2));
  375.         float vzdal_3 = sqrtf(pow((F1[j] - centr_1[2]), 2) + pow((F2[j] - centr_2[2]), 2));
  376.        
  377.         //printf("Vzdal 1 = %f, Vzdal 2 = %f, Vzdal 3 = %f \n\n", vzdal_1, vzdal_2, vzdal_3);
  378.        
  379.         if ((vzdal_1 < vzdal_2) && (vzdal_1 < vzdal_3))
  380.         {
  381.             type[j] = 1;
  382.         }
  383.         else if ((vzdal_2 < vzdal_1) && (vzdal_2 < vzdal_3))
  384.         {
  385.             type[j] = 2;
  386.         }
  387.         else if ((vzdal_3 < vzdal_1) && (vzdal_3 < vzdal_2))
  388.         {
  389.             type[j] = 3;
  390.         }
  391.         switch (type[j])
  392.         {
  393.             case 1:
  394.                 printf("The object %d with the center in [%f, %f] is SQUARE \n\n", j + 1, x_T[j], y_T[j]);
  395.                 cv::putText(index, "S", cv::Point(x_T[j], y_T[j]), FONT_ITALIC, 0.6, Scalar(150, 0, 1), false);
  396.                 break;
  397.             case 2:
  398.                 printf("The object %d with the center in [%f, %f] is STAR \n\n", j + 1, x_T[j], y_T[j]);
  399.                 cv::putText(index, "*", cv::Point(x_T[j], y_T[j]), FONT_ITALIC, 0.6, Scalar(150, 0, 1), false);
  400.                 break;
  401.             case 3:
  402.                 printf("The object %d with the center in [%f, %f] is RECTANGLE \n\n", j + 1, x_T[j], y_T[j]);
  403.                 cv::putText(index, "R", cv::Point(x_T[j], y_T[j]), FONT_ITALIC, 0.6, Scalar(150, 0, 1), false);
  404.                 break;
  405.         }
  406.     }
  407.    
  408.     cv::imshow("SRC", src_img);
  409.     //cv::imshow("G", g_img);
  410.     cv::imshow("KMEAN", index);
  411.    
  412.    
  413.    
  414.    
  415.    
  416.     delete[] m10;
  417.     m10 = NULL;
  418.     delete[] m01;
  419.     m01 = NULL;
  420.     delete[] x_T;
  421.     x_T = NULL;
  422.     delete[] y_T;
  423.     y_T = NULL;
  424.     delete[] my02;
  425.     my02 = NULL;
  426.     delete[] my20;
  427.     my20 = NULL;
  428.     delete[] my00;
  429.     my00 = NULL;
  430.     delete[] my11;
  431.     my11 = NULL;
  432.     delete[] perimeter;
  433.     perimeter = NULL;
  434.     delete[] F1;
  435.     F1 = NULL;
  436.     delete[] F2;
  437.     F2 = NULL;
  438.     delete[] type;
  439.     type = NULL;
  440.    
  441.    
  442.     delete[] one_1;
  443.     one_1 = NULL;
  444.     delete[] two_1;
  445.     two_1 = NULL;
  446.     delete[] three_1;
  447.     three_1 = NULL;
  448.    
  449.     delete[] one_2;
  450.     one_2 = NULL;
  451.     delete[] two_2;
  452.     two_2 = NULL;
  453.     delete[] three_2;
  454.     three_2 = NULL;
  455.    
  456.     delete[] Type;
  457.     Type = NULL;
  458.    
  459.     cv::waitKey(0);
  460. }
Advertisement
Add Comment
Please, Sign In to add comment