Ask Your Question
0

Line detection method

asked 2015-08-20 07:33:03 -0600

joe gravatar image

updated 2015-08-20 07:43:47 -0600

Hi Guys, I'm trying to do some project to detect um object in microscope. I'm using OpenCV for some time, but I dont underestand everything...

Goal is:

  1. with movable cursor find centre line of two rectangular object
  2. find contour line in each quadrant
  3. via start and end point find if rectangles are parallel
  4. print out diff angle, draw contour lines
  5. calculate rectangles middle line and print distance of lines in center
  6. ALL OF IT DO FAST (2-10 FPS)

I'm using Qt with c\c++ and openCV

This is my image after BW threshold This is my image after BW threshold

And this is my image after Canny And this is my image after Canny

I'm not able to find lines after Canny via HoughLineP, and I don't know why

Can you suggest my why ? Here is my source code

if(mat_orig.empty() == false)

   {
      cvtColor(mat_orig,mat_orig,CV_RGB2GRAY);
      int cursor_x, top_limit, bot_limit;
      int w_second;
      int h_mid;
      int o_x, o_y;

  o_x = mat_orig.cols;
  o_y = mat_orig.rows;

  cursor_x    = mat_orig.cols/2;                          //Here should be number from mouse x coord
  top_limit   = o_y/2 - o_y*0.05;
  bot_limit   = o_y/2 + o_y*0.05;

  w_second    = o_x - cursor_x;
  h_mid       = o_y - (2 * top_limit);

  //Make Partition
  mat_part[0]     = mat_orig(Rect(0,                0, cursor_x, top_limit));
  mat_part[1]     = mat_orig(Rect(cursor_x,         0, w_second, top_limit));
  mat_part[2]     = mat_orig(Rect(0,        bot_limit, cursor_x, top_limit));
  mat_part[3]     = mat_orig(Rect(cursor_x, bot_limit, w_second, top_limit));
  mat_part_mid    = mat_orig(Rect(0,        top_limit,      o_x,     h_mid));

  // some vars for process 
  int i=0;
  vector<Vec4i> lines;
  Vec4i l;
  int dy_max = 1;
  char points[50];

  //loop calculate thresh, canny and hough for all 4 quads
  for (i=0; i<4; i++)
  {
     threshold(mat_part[i], mat_part[i], 0, 255, CV_THRESH_BINARY + CV_THRESH_OTSU);
     Canny(mat_part[i], mat_part[i], 200, 600, 3,true);
     HoughLinesP(mat_part[i], lines, 1, CV_PI/(180), 300, 200, 0);
     cvtColor(mat_part[i], mat_part[i],CV_GRAY2RGB);

     //I need draw only longest line, not borders!
     for( size_t j = 0; j < lines.size(); j++ )
     {
        if((lines[j][0] > 10)  || 
            (lines[j][0] < (mat_part[j].cols - 10)) || 
            (lines[j][2] > 10)  || 
            (lines[j][2] < (mat_part[j].cols - 10)))
        {
           continue;
        }

        int dy = abs(lines[j][1] - lines[j][3]);
        if (dy > dy_max)
        {
           dy_max = dy;
           l = lines[j];
        }
     }
     //draw longest
     line(mat_part[i],Point(l[0],l[1]),Point(l[2],l[3]),Scalar(255,0,0),1);
  }
  cvtColor(mat_part_mid, mat_part_mid,CV_GRAY2RGB);

  //middle horizontal line (need visible horizontal center of image)
  line(mat_part_mid,Point(0,mat_part_mid.rows/2),Point(mat_part_mid.cols,mat_part_mid.rows/2),
         Scalar(255,0,255),1);

  //pic reconstruction
  hconcat(mat_part[0],mat_part[1],mat_part_top);
  hconcat(mat_part[2],mat_part[3],mat_part_bot);
  vconcat(mat_part_top, mat_part_mid, mat_part_tm);
  vconcat(mat_part_tm, mat_part_bot, mat_part_whole);

  cvtColor(mat_part_whole,mat_canny_view,CV_GRAY2RGB);
  cv::resize(mat_canny_view,mat_canny_view_s,sizeMat);
  QImage qimgProcCanny((uchar*)mat_canny_view_s.data, mat_canny_view_s.cols, mat_canny_view_s.rows,    
                                       mat_canny_view_s.step, QImage::Format_RGB888);
  ui->label_result->setPixmap(QPixmap::fromImage(qimgProcCanny));
edit retag flag offensive close merge delete

Comments

i wonder why "with movable cursor find centre line of two rectangular object" ? IMHO you can find it easily

sturkmen gravatar imagesturkmen ( 2015-08-20 09:45:57 -0600 )edit

I have to set division point for quadrant partition, its quite hard to set threshold in whole frame, so I divided it into 4 parts and calculate it four times

joe gravatar imagejoe ( 2015-08-20 09:51:05 -0600 )edit

i tried to test and understand your code. IMHO you can do what you want by better way using cv::findContours, approxPolyDP,RotatedRect etc.

sturkmen gravatar imagesturkmen ( 2015-08-20 11:11:39 -0600 )edit

I Thank you for your ideas! I tried findContours and I find that usefull, but I need to split curves and aproximate just line from len/fiber siluete. thats where I'll try use PCA as you suggest! you really helped me! Thanks!

joe gravatar imagejoe ( 2015-08-27 07:10:35 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
3

answered 2015-09-08 09:16:18 -0600

joe gravatar image

my solution is

threshold(mat_part[i], mat_part[i], 0, 255, CV_THRESH_BINARY + CV_THRESH_OTSU);
findContours(mat_part[i],contour,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE);

for(k = 0; k < contour.size(); k++)
         {
            ///skip contours with smaller size than specified area
            double area = contourArea(contour[k]);
            if (area > area_max)
            {
             area_max = area;
             index_of_area_max = k;
            }
         }
for(size_t j = 0; j < contour[index_of_area_max].size();j++) // run until j < contours[i].size();
         {
            pold = pixel;
            pixel = Point(contour[index_of_area_max][j]); //do whatever
            if (pixel.x > 10 && pixel.x < (max_x-10))
            {
               line_to_draw.push_back(pixel);
            }

aproximation to line with  my own function
print out

Thanks Folks!

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2015-08-20 07:33:03 -0600

Seen: 1,328 times

Last updated: Sep 08 '15