# Draw lines from centroid of contour at given angle till edge of contour

I have a contour named 'cnt' obtained from the image below:

for which I am able to find the centroid like this:

M = cv2.moments(cnt)
centroid_x = int(M['m10']/M['m00'])
centroid_y = int(M['m01']/M['m00'])


I now want to draw N number of lines, each 360/N degrees apart, starting from the centroid and passing through all possible points of intersection with the contour. The cv2.line() function requires start point and end point but I don't have the end point.

If I had drawn a line passing through centroid with a slope of Tan(360/N) I would have found the intersection of the line with the contour using bitwise_and but I'm not able to figure out a way to draw that line.

Any help would be much appreciated.

edit retag close merge delete

Sort by » oldest newest most voted

it's a bit of a shame, that you can't access the LineIterator from python, as it saves you from finding the intersection point manually, you'd just walk on with your line, until you reach a border pixel (or the image bounds) :

Mat ocv = imread("k4eIlCQ.png");
Mat gray; cvtColor(ocv,gray,COLOR_BGR2GRAY);
threshold(gray,gray,100,255,0);

Moments M = moments(gray);
Point cen( int(M.m10/M.m00), int(M.m01/M.m00) );

for (int i=0; i<360; i+=20)
{
double s = sin(i*CV_PI/180);
double c = cos(i*CV_PI/180);
Point p2(cen.x+s*150, cen.y+c*150); // any radius will do, we just want the direction

LineIterator it(ocv, cen, p2, 8);
Rect bounds(0, 0, ocv.cols, ocv.rows);
while(bounds.contains(it.pos()))
{
Vec3b & pixel = ocv.at<Vec3b>(it.pos());
// if you stare really hard, you'll see the cheat ;)
if (pixel[0] > 50) // non dark(it's not really black in the image!)
pixel[1] = pixel[2] = 0; // set g and b to 0, leaves blue line
else
break;
it++;
}
}
imshow("lines", ocv);


more

1

perfect!!!! I like it ;-).

( 2015-02-26 06:12:57 -0500 )edit
1

i think there must be a marker (maybe a new special tag like "Perfect_Solution" ) to mark all questions like this one. by this way newcomers easily find such good answers. @StevenPuttemans, @berak what is your opinion.

( 2015-08-22 03:26:45 -0500 )edit

actually regarding to what we were talking about making some changes in the form of the forum it would be nice answers with high voting rate to be marked as sticky in addition with some other threads like faq, rules, maybe job openings, etc...

( 2015-08-23 15:19:19 -0500 )edit

@both be patient. I passed on this concerns to the dev team and they told me they would get back with answers mid september.

( 2015-08-31 08:17:26 -0500 )edit

Hi @samkhan !

I think you are trying to find contour points that are at certain angle from centroid of that contour. Please follow the above steps:

1. Find minenclosing circle of that contour.
2. Find Point on the circle on a given angle. You can refer this Answer
3. Find all the Points on the Line segment using Line Iterator.
4. Loop through all the contour points & find the Distance between two points(Contour Point & Point on the Line).
5. Find the Point with minimum distance which is the Intersection Point P.
6. Draw a Line from Centroid C to Point P.

Hope you understand this simple explanation & I'll leave the code part for you!

more

Altough the approach by @Balaji will probably work without any problems, I do think this can be done much easier. From an angle and a starting point one can use mathematics to derive the function that represents the line. Once you have done that the following steps are quite easy.

• Define for each border (edge of mat) the value of the function. For example if your top border equals the equation x = 0, then you can define the y value of your line equation and see if that still falls within the range of your top edge.
• For each line you want to draw there will be only 2 points possible on your matrix. This also allows you only to draw lines for 180 degrees and get all 360 degree segments. Then use those two matching points to draw your line.

Necessary equation: http://stackoverflow.com/questions/15...

more

1

Yes that is correct! Step 1 is unnecessary.

( 2015-02-25 05:48:10 -0500 )edit
1

that assumes, you have a function for the outline. if not, all you probably got there is a contour, a vector of points, and you'd have to do an intersection check for each consecutive pairs/lines

( 2015-02-26 06:23:32 -0500 )edit

Well I was going to split the image segments over the complete image :D Not only the contour :P

( 2015-02-26 06:28:25 -0500 )edit