fenaux
fenaux

Reputation: 47

How to find intersection of lines with opencv

In this picture, I try to fin intersection points between the long white lines between racing lanes and the short perpendicular ones

enter image description here So to automaticaly obtain the black points as materialized below enter image description here

Here is my code:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button

import cv2

image = cv2.imread('80_frame140.png')


def get_white_2(img, low_threshold, high_threshold):
    
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    kernel_size = 5
    blur = cv2.GaussianBlur(gray, (kernel_size, kernel_size),0)
    
    edges = cv2.Canny(blur, low_threshold, high_threshold)
    
    return edges

def get_lines(edges, min_length, max_gap):

    rho = 1  # distance resolution in pixels of the Hough grid
    theta =  0.5* np.pi / 180  # 0.5 angular resolution in radians of the Hough grid
    threshold = 10#15 # minimum number of votes (intersections in Hough grid cell)
    min_line_length = min_length  # minimum number of pixels making up a line
    max_line_gap = max_gap # maximum gap in pixels between connectable line segments
    
    # Run Hough on edge detected image
    # Output "lines" is an array containing endpoints of detected line segments
    lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]),
                        min_line_length, max_line_gap)
    
    line_img = edges.copy() * 0
    for line in lines:
        for x1,y1,x2,y2 in line:
            cv2.line(line_img,(x1,y1),(x2,y2),(255),2)

    return line_img

def update_1(val):
    imgplot.set_data(get_white_2(image, int(low_slider.val), int(high_slider.val)))
    fig.canvas.draw_idle()
    
def line_button(event):
    plt.close('all')
    
def update_2(val):
    imgplot.set_data(get_lines(where_white, int(min_length_slider.val), int(max_gap_slider.val)))
    fig.canvas.draw_idle()

def main():
    # Define initial parameter
    init_low = 145
    init_high = 150
    
    
    # Create the figure and the line that we will manipulate
    fig, ax = plt.subplots()
    imgplot = plt.imshow(get_white_2(image, init_low, init_high), cmap='gray')
    #ax.set_xlabel('Time [s]')
    
    axcolor = 'lightgoldenrodyellow'
    ax.margins(x=0)
    
    # adjust the main plot to make room for the sliders
    plt.subplots_adjust(left=0.25, bottom=0.25)
    
    # Make a horizontal slider to control low_threshold.
    ax_low= plt.axes([0.25, 0.1, 0.65, 0.03], facecolor=axcolor)
    low_slider = Slider(
        ax=ax_low,
        label='low_threshold',
        valmin=0,
        valmax=150,
        valinit=init_low,
    )
    
    # Make a vertically oriented slider to control high_threshold
    ax_high = plt.axes([0.1, 0.25, 0.0225, 0.63], facecolor=axcolor)
    high_slider = Slider(
        ax=ax_high,
        label='high_threshold',
        valmin=100,
        valmax=255,
        valinit=init_high,
        orientation="vertical"
    )
    # The function to be called anytime a slider's value changes
    
    # register the update function with each slider
    low_slider.on_changed(update_1)
    high_slider.on_changed(update_1)
    
    # Create a `matplotlib.widgets.Button` to go to k selection.
    lineax = plt.axes([0.8, 0.025, 0.1, 0.04])
    button = Button(lineax, 'Lines', color=axcolor, hovercolor='0.975')
    
    
    button.on_clicked(line_button)
    where_white = get_white_2(image,int(low_slider.val), int(high_slider.val))
    
    plt.show()
    
    init_min_length = 50
    init_max_gap = 20
    # Create the figure and the line that we will manipulate
    fig, ax = plt.subplots()
    imgplot = plt.imshow(get_lines(where_white, init_min_length, init_max_gap), cmap='gray')
    
    axcolor = 'lightgoldenrodyellow'
    ax.margins(x=0)
    
    # adjust the main plot to make room for the sliders
    plt.subplots_adjust(left=0.25, bottom=0.25)
    
    # Make a horizontal slider to control min_line_length.
    ax_min_length = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor=axcolor)
    min_length_slider = Slider(
        ax=ax_min_length,
        label='min_length',
        valmin=5,
        valmax=100,
        valinit=init_min_length,
    )
    
    # Make a vertically oriented slider to control the max_gap
    ax_max_gap = plt.axes([0.1, 0.25, 0.0225, 0.63], facecolor=axcolor)
    max_gap_slider = Slider(
        ax=ax_max_gap,
        label='max_gap',
        valmin=0,
        valmax=30,
        valinit=init_max_gap,
        orientation="vertical"
    )
    
    min_length_slider.on_changed(update_2)
    max_gap_slider.on_changed(update_2)
    
    plt.show()
    
if __name__ =='__main__':
    main()

With the first image, I can get white parts detection:

enter image description here

With the second image, I can get le long lines

enter image description here

But I cannot find appropriate settings to detect perpendicular lines

enter image description here

Can anyone suggest appropriate settings or a better method

Upvotes: 1

Views: 1419

Answers (0)

Related Questions