if i got your idea correctly this will be something like this (please excuse my poor command over linear algebra)
import cv2
import numpy as np
def intersection(l0, l1): # (origin, drection), (origin, drection) -> point in scene coords
l0 = np.float32(l0)
l1 = np.float32(l1)
dOrg = l1[0] -l0[0]
g1ort = np.float32([-l1[1][1], l1[1][0]])
g0 = np.float32([l0[1][0], l0[1][1]])
if abs(np.dot(g0, g1ort)) < 1e-32:
return None
else:
t0 = np.dot(dOrg, g1ort)/np.dot(g0, g1ort)
return l0[0] +l0[1]*t0
img = np.zeros((450, 450, 3), dtype=np.uint8)
# badpoints = [[10,100], [180,250], [380,160], [220,360], [180,360], [70,210]]
points = [[200,100], [180,250], [380,160], [220,360], [180,360], [70,210]]
cont = [np.int32(points).reshape(len(points), 1, 2)] # convert it into this weird format cv so wants
cv2.drawContours(img, cont, -1, (0,0xff,0), 3)
leftmost = points[np.argmin(np.array(points)[:,0])]
hor_line = [leftmost, [100, 0]]
cont_lines = np.float32(list(zip(points, points[1:]+[points[0]]))) # make segment list (scene coords)
cont_lines = [[segment[0], segment[1]-segment[0]] for segment in cont_lines] # convert to parametric
intersections = [intersection(hor_line, line) for line in cont_lines] # cache intersection results for each segt
for pt in intersections:
if pt is not None:
cv2.circle(img, tuple(np.int32(pt)), 7, (0,0,255), 3)
rightmost = None
for isect, segt in zip(intersections, cont_lines):
if isect is not None:
gline = segt[1]
dOrg = isect -segt[0]
t = np.dot(gline, dOrg)/np.dot(gline, gline)
if 0 <= t <= 1: # check that only those intersection points that lie in boundaries of segments are used
if rightmost is None:
rightmost = isect
elif rightmost[0] < isect[0]:
rightmost = isect
cv2.circle(img, tuple(np.int32(rightmost)), 11, (255,0,0), 3)
cv2.imshow('test', img)
cv2.waitKey(0)
consider replacing points
array with badpoints
. this will result in leftmost point also being topmost, so that there is no matching segment to the right of it to intersect