matejnevlud

ANO - trida

Mar 2nd, 2021
582
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "stdafx.h"
  2. #include "objectprocessing.h"
  3.  
  4. ObjectProcessing::ObjectProcessing(){}
  5.  
  6. void ObjectProcessing::image_thresholding(cv::Mat &input, cv::Mat &output, float threshold)
  7. {
  8.     output = cv::Mat::zeros(input.size(), input.type());
  9.     for (int y = 1; y < input.rows - 1; y++) {
  10.         for (int x = 1; x < input.cols - 1; x++) {
  11.             if (input.at<float>(y, x) > threshold) {
  12.                 output.at<float>(y, x) = 1.0f;
  13.             }
  14.         }
  15.     }
  16. }
  17.  
  18. int ObjectProcessing::objects_indexing(cv::Mat & input, cv::Mat &output)
  19. {
  20.     output = cv::Mat::zeros(input.size(), input.type());
  21.     std::vector<cv::Point> points;
  22.     cv::Point lookForMatrix[]{
  23.         cv::Point(1, 1), cv::Point(1, 0), cv::Point(1, -1),
  24.         cv::Point(0, 1),                  cv::Point(0, -1),
  25.         cv::Point(-1, 1), cv::Point(-1, 0), cv::Point(-1, 1)
  26.     };
  27.     int lookForMatrixSize = sizeof(lookForMatrix) / sizeof(cv::Point); 
  28.     int o_id = 1;  
  29.     for (int y = 0; y < input.rows; y++) {
  30.         for (int x = 0; x < input.cols; x++) {
  31.             if (input.at<float>(y, x) != 0.0f) {
  32.                 bool indexed = false;
  33.                 points.push_back(cv::Point(x, y));
  34.  
  35.                 while (!points.empty()) {
  36.                     cv::Point point = points[points.size() - 1];
  37.                     points.pop_back();
  38.                     if (point.x > 0 && point.y > 0 && point.x < input.cols - 1 && point.y < input.rows - 1) {
  39.                         if (output.at<float>(point) != 0.0f) {
  40.                             continue;
  41.                         }
  42.                         for (int i = 0; i < lookForMatrixSize; i++) {
  43.                             cv::Point pointToCheck = point + lookForMatrix[i];
  44.                             if (input.at<float>(pointToCheck) != 0.0f) {
  45.                                 points.push_back(pointToCheck);
  46.                             }
  47.                         }
  48.                         indexed = true;
  49.                     }
  50.                     output.at<float>(point) = o_id;
  51.                 }
  52.                 if (indexed) {
  53.                     o_id++;
  54.                 }
  55.             }
  56.         }
  57.     }
  58.     return o_id;
  59. }
  60.  
  61. void ObjectProcessing::paint_objects(cv::Mat & source, cv::Mat & output, int objects)
  62. {
  63.     output = cv::Mat::zeros(source.size(), CV_32FC3);
  64.     std::vector<cv::Vec3f> colors;
  65.     colors.push_back(cv::Vec3f());
  66.  
  67.     for (int i = 0; i < objects; i++) {
  68.         colors.push_back(create_color());
  69.     }
  70.  
  71.     for (int y = 0; y < source.rows; y++) {
  72.         for (int x = 0; x < source.cols; x++) {
  73.             output.at<cv::Vec3f>(y, x) = colors[source.at<float>(y, x)];
  74.         }
  75.     }
  76. }
  77.  
  78. std::vector<float*> ObjectProcessing::features_extraction(cv::Mat & input, int objects, std::vector<float> &coordinate_areas, std::vector<float> &mass_areas, std::vector<float> &perimeters, std::vector<float> &F1, std::vector<float> &F2, std::vector<float> &uMin, std::vector<float> &uMax)
  79. {
  80.     std::vector<cv::Mat> coordinate_moments;
  81.     std::vector<cv::Mat> center_of_the_mass_moments;
  82.     std::vector<float*> centersOfMasses;
  83.     get_moments_for_coordinate(input, coordinate_moments, perimeters, objects);
  84.     get_moments_center_mass(input, coordinate_moments, center_of_the_mass_moments);
  85.     get_classification_moments(center_of_the_mass_moments, perimeters, F1, F2, uMin, uMax);
  86.     coordinate_areas = get_areas(coordinate_moments);
  87.     mass_areas = get_areas(center_of_the_mass_moments);
  88.     centersOfMasses = get_centers(coordinate_moments);
  89.     return centersOfMasses;
  90. }
  91.  
  92. std::vector<float*> ObjectProcessing::compute_etalons(cv::Mat &input, int objects, std::vector<float> &F1, std::vector<float> &F2, cv::Mat &output){
  93.     std::vector<float*> etalon_classes;
  94.     output = cv::Mat(input.size(), CV_32FC3, cv::Scalar(0.0, 0.0, 0.0));
  95.  
  96.     // check wrong data
  97.     for (int i = 1; i < objects; i++) {
  98.         if (isnan(F1[i]) || isnan(F2[i])) {
  99.             objects -= 1;
  100.             F1.erase(F1.begin() + i);
  101.             F2.erase(F2.begin() + i);
  102.         }
  103.     }
  104.  
  105.     float old_f1 = F1[1];
  106.     float old_f2 = F2[1];
  107.     float etalon_f1 = 0;
  108.     float etalon_f2 = 0;
  109.     int Nr = 0;
  110.     for (int i = 1; i < objects; i++) {    
  111.         cv::circle(output, cv::Point(F1[i] * output.cols, F2[i] * output.rows), 3, cv::Vec3f(1.0, 1.0, 1.0));
  112.         if (!isnan(F1[i]) && !isnan(F2[i])) {  
  113.             if (round(F1[i]) == round(old_f1) && round(F2[i]) == round(old_f2))    
  114.             {
  115.                 etalon_f1 += F1[i];
  116.                 etalon_f2 += F2[i];
  117.                 Nr += 1;
  118.             }
  119.             else {  // add etalon new class
  120.                 float *x = new float[2];
  121.                 x[0] = (1.0f / (float)Nr) * etalon_f1;
  122.                 x[1] = (1.0f / (float)Nr) * etalon_f2;
  123.                 etalon_classes.push_back(x);
  124.                 etalon_f1 = 0;
  125.                 etalon_f2 = 0;
  126.                 Nr = 0;
  127.             }
  128.             if (i == objects - 1) { // add etalon last class
  129.                 float *x = new float[2];
  130.                 x[0] = (1.0f / (float)Nr) * etalon_f1;
  131.                 x[1] = (1.0f / (float)Nr) * etalon_f2;
  132.                 etalon_classes.push_back(x);
  133.             }
  134.             old_f1 = F1[i];
  135.             old_f2 = F2[i];
  136.         }
  137.     }
  138.     for (int i = 0; i < etalon_classes.size(); i++) {
  139.         float *etalon = etalon_classes[i];
  140.         float x = etalon[0] * output.cols;
  141.         float y = etalon[1] * output.rows;
  142.         cv::Vec3f color = create_color();
  143.         cv::circle(output, cv::Point(x, y), 4, color, -1);
  144.     }
  145.  
  146.     return etalon_classes;
  147. }
  148.  
  149. void ObjectProcessing::classify_by_etalons(cv::Mat &input, cv::Mat &output, std::vector<float*> centerOfMasses, std::vector<float*> etalons, std::vector<float> &F1, std::vector<float> &F2, int objects) {
  150.     output = input.clone();
  151.     cv::cvtColor(output, output, cv::COLOR_GRAY2BGR);
  152.     std::vector<cv::Vec3f> colors;
  153.  
  154.     // check wrong data
  155.     for (int i = 1; i < objects; i++) {
  156.         if (isnan(F1[i]) || isnan(F2[i])) {
  157.             objects -= 1;
  158.             centerOfMasses.erase(centerOfMasses.begin() + i);
  159.             F1.erase(F1.begin() + i);
  160.             F2.erase(F2.begin() + i);
  161.         }
  162.     }
  163.  
  164.     for (int j = 0; j < etalons.size(); j++) {
  165.         colors.push_back(create_color());
  166.     }
  167.  
  168.     for (int i = 1; i < objects; i++) {
  169.         float distance = 100.0f;
  170.         float etalon_index;
  171.         for (int j = 0; j < etalons.size(); j++) {
  172.             float * etalon = etalons[j];
  173.             float x = etalon[0] - F1[i];
  174.             float y = etalon[1] - F2[i];
  175.             float dist;
  176.             dist = pow(x, 2) + pow(y, 2);    
  177.             dist = sqrt(dist);
  178.  
  179.             if (dist < distance)
  180.             {
  181.                 distance = dist;
  182.                 etalon_index = j;
  183.             }
  184.         }
  185.  
  186.         float *center = centerOfMasses[i];
  187.         cv::Vec3f color = colors[etalon_index];
  188.         cv::circle(output, cv::Point(center[0], center[1]), 7, color, -1);
  189.     }
  190.  
  191. }
  192.  
  193. std::vector<float*> ObjectProcessing::compute_kmeans(cv::Mat &input, int objects, std::vector<float> &F1, std::vector<float> &F2, cv::Mat &output, int numOfClusters, int &stepsOverall) {
  194.     std::vector<cv::Vec3f> colors;
  195.     output = cv::Mat(input.size(), CV_32FC3, cv::Scalar(0.0, 0.0, 0.0));
  196.     std::random_device rd;
  197.     std::mt19937 eng(rd());
  198.     std::uniform_int_distribution<> distrx(0, 1);
  199.     std::uniform_int_distribution<> distry(0, 1);
  200.  
  201.     std::vector<float*> centroids;
  202.     std::vector<float*> points;
  203.     bool find_new_centroids = true;
  204.  
  205.     // check wrong data
  206.     for (int i = 1; i < objects; i++) {
  207.         if (isnan(F1[i]) || isnan(F2[i])) {
  208.             objects -= 1;
  209.             F1.erase(F1.begin() + i);
  210.             F2.erase(F2.begin() + i);
  211.         }
  212.     }
  213.  
  214.     for (int i = 0; i < numOfClusters; i++) {
  215.         float *cent = new float[2];
  216.         cent[0] = distrx(eng);
  217.         cent[1] = distry(eng);
  218.         centroids.push_back(cent);
  219.         colors.push_back(create_color());
  220.     }
  221.  
  222.     for (int i = 1; i < objects; i++) {
  223.         float* point = new float[2];
  224.         point[0] = F1[i];
  225.         point[1] = F2[i];
  226.         points.push_back(point);
  227.         cv::circle(output, cv::Point(F1[i] * output.cols,F2[i] * output.rows), 3, cv::Vec3f(1.0, 1.0, 1.0));
  228.     }
  229.    
  230.     // main loop
  231.     std::vector<int> old_assignment;
  232.     while (find_new_centroids) {
  233.         std::vector<int> points_assignment_idx;
  234.         // distance for each point
  235.         for (int i = 0; i < points.size(); i++) {
  236.             int close_idx = 0;
  237.             float distance = 10000.0f;
  238.             float* point = new float[2];
  239.             point = points[i];
  240.  
  241.             for (int j = 0; j < centroids.size(); j++) {
  242.                 float dist;
  243.                 float *cent = centroids[j];
  244.                 dist = pow(cent[0] - point[0], 2) + pow(cent[1] - point[1], 2);
  245.                 dist = sqrt(dist);  // new distance
  246.                 if (dist < distance)
  247.                 {
  248.                     distance = dist;
  249.                     close_idx = j;
  250.                 }
  251.             }
  252.             points_assignment_idx.push_back(close_idx);
  253.         }
  254.  
  255.         // calculate new centroids
  256.         for (int i = 0; i < centroids.size(); i++) {
  257.             int numOfPoints = 0;
  258.             float meanx = 0;
  259.             float meany = 0;
  260.             for (int j = 0; j < points.size(); j++) {
  261.                 if (points_assignment_idx[j] == i) {    // if is assigned to centroid
  262.                     numOfPoints += 1;
  263.                     float *point = new float[2];
  264.                     point = points[j];
  265.                     meanx += point[0];
  266.                     meany += point[1];
  267.                 }
  268.             }
  269.             if (numOfPoints > 0) {
  270.                 float* cent = new float[2];
  271.                 cent[0] = meanx / numOfPoints;
  272.                 cent[1] = meany / numOfPoints;
  273.                 centroids[i] = cent;
  274.             }
  275.         }
  276.        
  277.         if (old_assignment == points_assignment_idx)
  278.             find_new_centroids = false;
  279.         else
  280.             old_assignment.swap(points_assignment_idx);
  281.         stepsOverall++;
  282.     }
  283.     // end of loop - final centroids
  284.  
  285.     for (int i = 0; i < centroids.size(); i++) {
  286.         float * cent = centroids[i];
  287.         cv::circle(output, cv::Point(cent[0] * output.cols, cent[1] * output.rows), 4, colors[i], -1);
  288.     }
  289.     return centroids;
  290. }
  291.  
  292. void ObjectProcessing::classify_by_kmeans(cv::Mat &input, cv::Mat &output, std::vector<float*> centerOfMasses, std::vector<float*> kmeans, std::vector<float> &F1, std::vector<float> &F2, int objects) {
  293.     output = input.clone();
  294.     cv::cvtColor(output, output, cv::COLOR_GRAY2BGR);
  295.     std::vector<cv::Vec3f> colors;
  296.  
  297.     // check wrong data
  298.     for (int i = 1; i < objects; i++) {
  299.         if (isnan(F1[i]) || isnan(F2[i])) {
  300.             objects -= 1;
  301.             centerOfMasses.erase(centerOfMasses.begin() + i);
  302.             F1.erase(F1.begin() + i);
  303.             F2.erase(F2.begin() + i);
  304.         }
  305.     }
  306.  
  307.     for (int j = 0; j < kmeans.size(); j++) {
  308.         colors.push_back(create_color());
  309.     }
  310.  
  311.     for (int i = 1; i < objects; i++) {
  312.         float distance = 10000.0f;
  313.         float centroid_index = 0;
  314.         for (int j = 0; j < kmeans.size(); j++) {
  315.             float * kmean = kmeans[j];
  316.             float x = kmean[0] - F1[i];
  317.             float y = kmean[1] - F2[i];
  318.             float dist;
  319.             dist = pow(x, 2) + pow(y, 2);
  320.             dist = sqrt(dist);
  321.  
  322.             if (dist < distance)
  323.             {
  324.                 distance = dist;
  325.                 centroid_index = j;
  326.             }
  327.         }
  328.  
  329.         float *center = centerOfMasses[i];
  330.         cv::Vec3f color = colors[centroid_index];
  331.         cv::circle(output, cv::Point(center[0], center[1]), 7, color, -1);
  332.     }
  333.  
  334. }
  335.  
  336. void ObjectProcessing::put_index_numbers_in_image(cv::Mat &source, std::vector<float*> centerOfMasses, std::vector<float> &F1, std::vector<float> &F2, int objects) {
  337.     float f1 = F1[1];
  338.     float f2 = F2[1];
  339.     int oid = 1;
  340.     for (int i = 1; i < objects; i++) {
  341.         float *cn = centerOfMasses[i];
  342.         if (round(F1[i]) == round(f1) && round(F2[i]) == round(f2))
  343.             cv::putText(source, IntToString(oid), cv::Point(cn[0], cn[1]), cv::FONT_HERSHEY_SIMPLEX, 0.3, cv::Scalar(0.0, 0.0, 0.0));
  344.         else {
  345.             oid++;
  346.             cv::putText(source, IntToString(oid), cv::Point(cn[0], cn[1]), cv::FONT_HERSHEY_SIMPLEX, 0.3, cv::Scalar(0.0, 0.0, 0.0));
  347.         }
  348.         f1 = F1[i];
  349.         f2 = F2[i];
  350.     }
  351. }
  352.  
  353. void ObjectProcessing::get_moments_for_coordinate(cv::Mat & input, std::vector<cv::Mat>& moments, std::vector<float>& perimeters, int objects)
  354. {
  355.     for (int i = 0; i < objects; i++) {
  356.         moments.push_back(cv::Mat::zeros(cv::Size(2, 2), input.type()));
  357.         perimeters.push_back(0.0f);
  358.     }
  359.     cv::Point lookForMatrix[]{
  360.         cv::Point(1, 0),
  361.         cv::Point(0, 1),               
  362.         cv::Point(0, -1),
  363.         cv::Point(-1, 0)
  364.     };
  365.     int lookForMatrixSize = sizeof(lookForMatrix) / sizeof(cv::Point); 
  366.  
  367.     for (int y = 0; y < input.rows; y++) {
  368.         for (int x = 0; x < input.cols; x++) {
  369.             int o_id = 0;
  370.             if ((o_id = input.at<float>(y, x)) != 0.0f) {
  371.                 cv::Mat objectMoment = moments[o_id];
  372.                 for (int q = 0; q < objectMoment.rows; q++) {
  373.                     for (int p = 0; p < objectMoment.cols; p++) {
  374.                         objectMoment.at<float>(q, p) += pow(x, p) * pow(y, q);
  375.                     }
  376.                 }
  377.                 moments[o_id] = objectMoment;
  378.                 cv::Point point = cv::Point(x, y);
  379.  
  380.                 if (point.x > 0 && point.y > 0 && point.x < input.cols - 1 && point.y < input.rows - 1) {
  381.                     int perimeterCounter = 0;
  382.                     for (int i = 0; i < lookForMatrixSize; i++) {
  383.                         cv::Point pointToCheck = point + lookForMatrix[i];
  384.                         if (input.at<float>(pointToCheck) == o_id) {
  385.                             perimeterCounter++;
  386.                         }
  387.                     }
  388.                     if (perimeterCounter != lookForMatrixSize) {
  389.                         perimeters[o_id]++;
  390.                     }
  391.                 }
  392.             }
  393.         }
  394.     }
  395. }
  396.  
  397. void ObjectProcessing::get_moments_center_mass(cv::Mat & input, std::vector<cv::Mat>& coordMoments, std::vector<cv::Mat>& massMoments)
  398. {
  399.     for (int i = 0; i < coordMoments.size(); i++) {
  400.         massMoments.push_back(cv::Mat::zeros(cv::Size(3, 3), input.type()));
  401.     }
  402.     for (int y = 0; y < input.rows; y++) {
  403.         for (int x = 0; x < input.cols; x++) {
  404.             int o_id = 0;
  405.             if ((o_id = input.at<float>(y, x)) != 0.0f) {
  406.                 cv::Mat objectMoment = massMoments[o_id];
  407.                 for (int q = 0; q < objectMoment.rows; q++) {
  408.                     for (int p = 0; p < objectMoment.cols; p++) {
  409.                         float* centerOfMass = get_center(coordMoments[o_id]);
  410.                         objectMoment.at<float>(q, p) += pow(x - centerOfMass[0], p) * pow(y - centerOfMass[1], q);
  411.                         delete centerOfMass;
  412.                     }
  413.                 }
  414.                 massMoments[o_id] = objectMoment;  
  415.             }
  416.         }
  417.     }
  418. }
  419.  
  420. void ObjectProcessing::get_classification_moments(std::vector<cv::Mat>& inputMoments, std::vector<float>& inputPerimeters, std::vector<float>& F1, std::vector<float>& F2, std::vector<float>& uMin, std::vector<float>& uMax)
  421. {
  422.     for (int i = 0; i < inputMoments.size(); i++) {
  423.         F1.push_back(get_F1(inputPerimeters[i], get_area(inputMoments[i])));
  424.         uMin.push_back(get_uMin(inputMoments[i]));
  425.         uMax.push_back(get_uMax(inputMoments[i]));
  426.         F2.push_back(get_F2(uMin[i], uMax[i]));
  427.     }
  428. }
  429.  
  430. float ObjectProcessing::get_F1(float perimeter, float area)
  431. {
  432.     return pow(perimeter, 2) / (100.0f * area);
  433. }
  434.  
  435. float ObjectProcessing::get_F2(float uMin, float uMax)
  436. {
  437.     return uMin / uMax;
  438. }
  439.  
  440. float ObjectProcessing::get_uMin(cv::Mat centerOfTheMassMoment)
  441. {
  442.     return 0.5f * (centerOfTheMassMoment.at<float>(0, 2) + centerOfTheMassMoment.at<float>(2, 0)) - 0.5f * sqrt(4 * pow(centerOfTheMassMoment.at<float>(1, 1), 2) + pow(centerOfTheMassMoment.at<float>(0, 2) - centerOfTheMassMoment.at<float>(2, 0), 2));
  443. }
  444.  
  445. float ObjectProcessing::get_uMax(cv::Mat centerOfTheMassMoment)
  446. {
  447.     return 0.5f * (centerOfTheMassMoment.at<float>(0, 2) + centerOfTheMassMoment.at<float>(2, 0)) + 0.5f * sqrt(4 * pow(centerOfTheMassMoment.at<float>(1, 1), 2) + pow(centerOfTheMassMoment.at<float>(0, 2) - centerOfTheMassMoment.at<float>(2, 0), 2));
  448. }
  449.  
  450. std::vector<float> ObjectProcessing::get_areas(std::vector<cv::Mat>& inputMoments)
  451. {
  452.     std::vector<float> areas;
  453.     for (int i = 0; i < inputMoments.size(); i++) {
  454.         areas.push_back(get_area(inputMoments[i]));
  455.     }
  456.     return areas;
  457. }
  458.  
  459. std::vector<float*> ObjectProcessing::get_centers(std::vector<cv::Mat>& coordinateMoments)
  460. {
  461.     std::vector<float*> centersOfMasses;
  462.     for (int i = 0; i < coordinateMoments.size(); i++) {
  463.         centersOfMasses.push_back(get_center(coordinateMoments[i]));
  464.     }
  465.     return centersOfMasses;
  466. }
  467.  
  468. float ObjectProcessing::get_area(cv::Mat objectMoment)
  469. {
  470.     return objectMoment.at<float>(0, 0);
  471. }
  472.  
  473. float *ObjectProcessing::get_center(cv::Mat coordinateMoment)
  474. {
  475.     float* center = new float[2];
  476.     center[0] = coordinateMoment.at<float>(0, 1) / coordinateMoment.at<float>(0, 0);
  477.     center[1] = coordinateMoment.at<float>(1, 0) / coordinateMoment.at<float>(0, 0);
  478.     return center;
  479. }
  480.  
  481. cv::Vec3f ObjectProcessing::create_color()
  482. {
  483.     std::random_device rd;
  484.     std::mt19937 eng(rd());
  485.     std::uniform_int_distribution<> distr(50, 255);
  486.     return cv::Vec3f(float(distr(eng)) / 255, float(distr(eng)) / 255, float(distr(eng)) / 255);
  487. }
  488.  
  489. std::string ObjectProcessing::IntToString(int Number)
  490. {
  491.     std::ostringstream ss;
  492.     ss << Number;
  493.     return ss.str();
  494. }
  495.  
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×