Рисование эквидистантных сегментов в python с помощью opencv - PullRequest
0 голосов
/ 27 мая 2020

Для данного изображения я рисую линию внутри него следующим образом:

def slope(x1,y1,x2,y2):

    ###finding slope
    if x2!=x1:
        return((y2-y1)/(x2-x1))
    else:
        return 'NA'

def draw_line(image,lineThickness, colors, points):
    x1,y1, x2, y2=points
    m=slope(x1,y1,x2,y2)
    h,w=image.shape[:2]
    if m!='NA':
        px=0
        py=-(x1-0)*m+y1
        ##ending point
        qx=w
        qy=-(x2-w)*m+y2
    else:
    ### if slope is zero, draw a line with x=x1 and y=0 and y=height
        px,py=x1,0
        qx,qy=x1,h

    cv2.line(image, (int(px), int(py)), (int(qx), int(qy)), colors, lineThickness)
    return (px, py), (qx, qy)

Этот код (исходящий из SA) гарантирует, что данная линия (определенная двумя точками) покрывает все image.

Теперь я хотел бы нарисовать несколько параллельных линий на одном изображении с параметрами, указывающими, насколько линии должны быть удалены друг от друга

Моя текущая попытка заключается в следующем :

#Utility to find if two segments intersect
def ccw(A,B,C):
    Ax, Ay = A
    Bx, By = B
    Cx, Cy = C
    return (Cy-Ay) * (Bx-Ax) > (By-Ay) * (Cx-Ax)

#Utility to find if two segments intersect
def intersect(A,B,C,D):
    return ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)

#Utility to find if a segment intersect a square
def intersect_square(A,B, s_size):
    C = (1,1)
    D = (1, s_size-1)
    E = (s_size-1, +1)
    F = (s_size-1, s_size-1)
    return (ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)) or \
            (ccw(A,E,F) != ccw(B,E,F) and ccw(A,B,E) != ccw(A,B,F)) or \
            (ccw(A,C,E) != ccw(B,C,E) and ccw(A,B,C) != ccw(A,B,E)) or  \
            (ccw(A,D,F) != ccw(B,D,F) and ccw(A,B,D) != ccw(A,B,F))

#Utility to draw a white canvas         
def draw_white_image(x_size,y_size):
    img = np.zeros([x_size,y_size,3],dtype=np.uint8)
    img.fill(255) # or img[:] = 255
    return img

def draw_parallel_lines(img, thickness, colors, points, space):

    #Draw the first line
    draw_line(img, thickness, colors, points)
    x1, y1, x2, y2 = points
    flag = True
    while(flag):
        y1 += space
        y2 += space
        new_points = draw_line(img, thickness, colors, (x1,y1,x2,y2))
        flag = intersect_square(new_points[0], new_points[1], h)

Этот код перемещает координаты y моих начальных точек до тех пор, пока новые линии, которые я генерирую, не выйдут за пределы квадрата. К сожалению, этот код дает следующий результат:

enter image description here

Строки не равноудалены. Я потратил на это несколько часов, и теперь мне немного грустно. Пожалуйста, помогите

1 Ответ

1 голос
/ 27 мая 2020

Если сегмент линии определяется точками (x1,y1) и (x2,y2), он имеет вектор направления:

(dx, dy) = (x2-x1, y2-y1)

Нормализованный вектор (единичная длина):

len = sqrt((x2-x1)^2 + (y2-y1)^2)
(udx, udy) = (dx / len, dy / len)

Перпендикулярный вектор :

(px, py) = (-udy, udx)  

Базовая точка для параллельной линии на расстоянии dist:

(x1', y1') = (x1 + px * dist, y1 + py * dist)
or
(x1', y1') = (x1 - udy * dist, y1 + udx * dist) 

Другая конечная точка:

(x2', y2') = (x1' + dx, y1' + dy)

Чтобы получить параллельную линию в другом направлении , отрицать знаки px,py

...