Ask Your Question

How to slice image with respect to horizontal line pattern

asked 2016-11-29 12:25:58 -0500

VishalNair gravatar image

updated 2016-11-29 12:26:56 -0500

I am new to opencv and trying out segmenting operations. I have this processed image as follows --> image description

I want to slice the image into separate blocks only if the line covers about 70% of the total width as shown in below image -->

image description

I tried HoughLine Transform as given in this link but the results were completely wrong and not even close. Please explain how to solve this problem with code.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2016-11-29 12:44:42 -0500

Tetragramm gravatar image

updated 2016-11-29 13:17:47 -0500

I think the example was intended for something smaller than your image. Try this.

EXPLANATION EDIT: I extended the size of the lines it draws to 5000 pixels, cause it's a big image. The most important changes are to the HoughLines call.

  • The (1) is rho is the distance of the accumulator in pixels, and I just used the value from the tutorial.
  • The (CV_PI/180) is the angular resolution of the accumulator in radians, and this is a value of 1 degree.
  • The (dst.cols*0.5) is the number of pixels that must be accumulated to count as a line, which I have set to half the width of the image. This is your main control over what qualifies as a line.
  • The (0, 0) are telling it to use the classical Hough transform, not the multi-scale one.
  • The (89 * CV_PI / 180, 91 * CV_PI / 180) are the min and max theta. Since 0 is a vertical line, and you just want horizontal lines, we restrict it to a small distance +/- 1 degree around 90. You can possibly make this even smaller. Probably, just 90/90. That might get rid of the duplicates.


Mat dst = imread("lines.jpg");
Mat cdst = dst.clone();
cvtColor(dst, dst, COLOR_BGR2GRAY);
threshold(dst, dst, 1, 255, THRESH_BINARY);
vector<Vec2f> lines;
HoughLines(dst, lines, 1, CV_PI / 180, dst.cols*0.5, 0, 0, 89 * CV_PI / 180, 91 * CV_PI / 180);

for (size_t i = 0; i < lines.size(); i++)
    float rho = lines[i][0], theta = lines[i][1];
    Point pt1, pt2;
    double a = cos(theta), b = sin(theta);
    double x0 = a*rho, y0 = b*rho;
    pt1.x = cvRound(x0 + 5000 * (-b));
    pt1.y = cvRound(y0 + 5000 * (a));
    pt2.x = cvRound(x0 - 5000 * (-b));
    pt2.y = cvRound(y0 - 5000 * (a));
    line(cdst, pt1, pt2, Scalar(0, 0, 255), 3, CV_AA);
imshow("source", dst);
imshow("detected lines", cdst);
edit flag offensive delete link more


thanks pretty better results !! Can you explain a bit and also sometimes one extra line is getting added on the same line.

VishalNair gravatar imageVishalNair ( 2016-11-29 12:58:37 -0500 )edit

@Tetragramm - Great explanation thanks a lot !!! .Plus just would like to mention a graphical representation of what you explained -->

VishalNair gravatar imageVishalNair ( 2016-11-29 13:24:16 -0500 )edit

The dist.cols*0.5 Only lines with white in pixels equal to that number are returned. So you can adjust the length of lines needed by altering that number.

Tetragramm gravatar imageTetragramm ( 2016-11-29 13:39:41 -0500 )edit

also take a look at this. if your lines is perfectly horizontal you can use this code. it gives the rects you want.

sturkmen gravatar imagesturkmen ( 2016-11-29 13:41:56 -0500 )edit

@Tetragramm - O Sorry.My Mistake I missed the third point you mentioned in the answer .

VishalNair gravatar imageVishalNair ( 2016-11-29 13:43:30 -0500 )edit

Question Tools

1 follower


Asked: 2016-11-29 12:25:58 -0500

Seen: 2,200 times

Last updated: Nov 29 '16