# Line detection method

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

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 close merge delete

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

( 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

( 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.

( 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!

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

Sort by ยป oldest newest most voted

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!

more

Official site

GitHub

Wiki

Documentation