Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 8th, 2012  |  syntax: C++  |  size: 4.41 KB  |  hits: 31  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <opencv2/core/core.hpp>
  2. #include <opencv2/highgui/highgui.hpp>
  3. #include <iostream>
  4. #include <cmath>
  5.  
  6. #define PI 3.14159265
  7.  
  8. #define uchar unsigned char
  9.  
  10. using namespace std;
  11.  
  12. struct HoughLine
  13. {
  14.         double theta;
  15.         double r;
  16. };
  17.  
  18.  
  19.  
  20. int main( int argc, char** argv )
  21. {
  22.  
  23.         const int neighbourhoodSize = 4;
  24.         int maxTheta = 180;
  25.         double thetaStep = PI / maxTheta;
  26.         int ** houghArray;
  27.         float centerX, centerY;
  28.         int houghHeight;
  29.         int doubleHeight;
  30.         int numPoints;
  31.         double * sinCache;
  32.         double * cosCache;
  33.  
  34.         if(argc < 3)
  35.         {
  36.                 cout << "Usage: " << argv[0] <<" imageName threashold" << endl;
  37.                 return -1;
  38.         }
  39.  
  40.         cv::Mat img = cv::imread(argv[1], 0); //imagem original
  41.         cv::Mat linesImg;  // imagem linhas
  42.         cv::Mat houghImg;  // imagem espaço de hough
  43.  
  44.         int width = img.cols;
  45.         int height = img.rows;
  46.  
  47.         linesImg.create(height, width, CV_8UC1);
  48.         linesImg = 255;
  49.  
  50.  
  51.         houghHeight = (int)  (  sqrt(2.0) * std::max<int>(img.rows, img.cols));
  52.  
  53.         doubleHeight = 2 * houghHeight;
  54.  
  55.         houghArray = new int*[maxTheta];
  56.  
  57.         for(int i = 0 ; i<maxTheta; i++)
  58.         {
  59.                 houghArray[i] = new int[doubleHeight];
  60.                 memset(houghArray[i], 0, doubleHeight*sizeof(int));
  61.         }
  62.  
  63.         centerX = width / 2;
  64.         centerY = height / 2;
  65.  
  66.         numPoints = 0;
  67.  
  68.         sinCache = new double[maxTheta];
  69.         cosCache =  new double[maxTheta];
  70.  
  71.  
  72.         for (int t = 0; t < maxTheta; t++) {
  73.                 double realTheta = t * thetaStep;
  74.                 sinCache[t] = sin(realTheta);
  75.                 cosCache[t] = cos(realTheta);
  76.         }
  77.  
  78.  
  79.         for(int i=0; i< img.rows; i++)
  80.         {
  81.                 uchar * pixel = img.ptr<uchar>(i);
  82.  
  83.                 for( int j=0; j<img.cols; j++)
  84.                 {
  85.                         if(pixel[j] < 100)
  86.                         {
  87.                                 int x = j;
  88.                                 int y = img.rows - i;
  89.  
  90.                                 for (int t = 0; t < maxTheta; t++) {
  91.                                         int r = (int) (((x - centerX) * cosCache[t]) + ((y - centerY) * sinCache[t]));
  92.                                         r += houghHeight;
  93.                                         if (r < 0 || r >= doubleHeight) continue;
  94.  
  95.                                         houghArray[t][r]++;
  96.  
  97.                                 }
  98.                                 numPoints++;
  99.                         }
  100.                 }
  101.         }
  102.  
  103.  
  104.         vector<HoughLine> lines;
  105.  
  106.         float threshold = 0;
  107.         sscanf(argv[2], "%f", &threshold);
  108.         int newr;
  109.         int r;
  110.         bool onLoop = false;
  111.  
  112.  
  113.         if (numPoints != 0)
  114.         {
  115.                 for (int t = 0; t < maxTheta; t++)
  116.                 {
  117. loop:
  118.                         if(onLoop)
  119.                         {
  120.                                 newr = ++r;
  121.                                 onLoop = false;
  122.                         }
  123.                         else newr = neighbourhoodSize;
  124.  
  125.                         for (r = newr; r < doubleHeight - neighbourhoodSize; r++)
  126.                         {
  127.                                 if (houghArray[t][r] > threshold)
  128.                                 {
  129.                                         int peak = houghArray[t][r];
  130.  
  131.                                         for (int dx = -neighbourhoodSize; dx <= neighbourhoodSize; dx++)
  132.                                         {
  133.                                                 for (int dy = -neighbourhoodSize; dy <= neighbourhoodSize; dy++)
  134.                                                 {
  135.                                                         int dt = t + dx;
  136.                                                         int dr = r + dy;
  137.                                                         if (dt < 0) dt = dt + maxTheta;
  138.                                                         else if (dt >= maxTheta) dt = dt - maxTheta;
  139.                                                         if (houghArray[dt][dr] > peak) {
  140.                                                                 onLoop = true;
  141.                                                                 goto loop;
  142.                                                         }
  143.                                                 }
  144.                                         }
  145.  
  146.                                         double theta = t * thetaStep;
  147.  
  148.                                         // add the line to the vector
  149.                                         HoughLine l;
  150.                                         l.r = r;
  151.                                         l.theta = theta;
  152.                                         lines.push_back(l);
  153.                                 }
  154.                         }
  155.                 }
  156.         }
  157.  
  158.         cout << "Numero de linhas encontradas utilizando o threshold " << threshold << " : " <<lines.size() <<endl;
  159.         for(int i=0; i< lines.size(); i++)
  160.         {
  161.                 cout<<"Linha n"<<i<<": Theta " << lines[i].theta/thetaStep << " distancia do centro " << lines[i].r - houghHeight << endl;
  162.         }
  163.  
  164.         int max = 0;
  165.         for (int t = 0; t < maxTheta; t++) {
  166.                 for (int r = 0; r < doubleHeight; r++) {
  167.                         if (houghArray[t][r] > max) {
  168.                                 max = houghArray[t][r];
  169.                         }
  170.                 }
  171.         }
  172.  
  173.  
  174.         houghImg.create(doubleHeight, maxTheta, CV_8UC1);
  175.  
  176.         // desenha espaço de hough
  177.         for (int t = 0; t < maxTheta; t++) {
  178.                 for (int r = 0; r < doubleHeight; r++) {
  179.                         double value = 255.0 * ((double) houghArray[t][r]) / (double)max;
  180.                         int v = 255 - (int) value;
  181.                         houghImg.at<uchar>(r, t) = v;    
  182.                 }
  183.         }
  184.  
  185.  
  186.         // desenha linhas
  187.         for(int i=0; i< lines.size(); i++)
  188.         {
  189.                 for( int j=0; j<img.cols; j++)
  190.                 {
  191.                         double realTheta = lines[i].theta;
  192.                         double dcos = cos(realTheta);
  193.                         double dsin = sin(realTheta);
  194.                         double rr = lines[i].r - houghHeight;
  195.                         double first = rr - dcos * (j - img.cols/2);
  196.                         int y = first / dsin;
  197.                         y = img.rows - y;
  198.                         y-= img.rows/2;
  199.                         if(y >= 0 && y < img.rows)
  200.                                 linesImg.at<uchar>(y, j) = 0;
  201.                 }
  202.         }
  203.  
  204.  
  205.         cv::imshow( "Original Image", img );
  206.         cv::imshow( "Hough Image", houghImg );
  207.         cv::imshow( "Lines Image", linesImg );
  208.  
  209.         uchar c = 0;
  210.  
  211.         while(c != 27)
  212.         {
  213.                 c = cv::waitKey(0);  
  214.         }
  215.  
  216.         return 0;
  217. }