How to find intersection points between lines and contours

Question:

Consider the below image where contours is shown in green and straight lines are shown in red

enter image description here

how can we find point of intersections where straight lines cuts contours

import cv2 
from matplotlib import pyplot as plt
import numpy as np

# Read image img

# Binarize
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_,thresh = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)

# Find Contours
_, contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Draw Contours
blank_mask = np.zeros((thresh.shape[0],thresh.shape[1],3), np.uint8)
cv2.drawContours(blank_mask, contours, -1, (0, 255, 0), 1) 

# Define lines coordinates
line1 = [x1, y1, x2, y2]
line2 = [x1, y1, x2, y2]
line3 = [x1, y1, x2, y2]

# Draw Lines over Contours
cv2.line(blank_mask, (line1[0], line1[1]), (line1[2], line1[3]), (255, 0, 0), thickness=1)
cv2.line(blank_mask, (line2[0], line2[1]), (line2[2], line2[3]), (255, 0, 0), thickness=1)
cv2.line(blank_mask, (line3[0], line3[1]), (line3[2], line3[3]), (255, 0, 0), thickness=1)

# Show Image
fig = plt.figure()
ax  = fig.add_subplot(111)
ax.imshow(blank_mask)

Sample Image

Asked By: arush1836

||

Answers:

You can check pixel by pixel to see where they overlap. You have to keep a copy of the pixels where the contours are before drawing the lines, because that will overwrite the overlapping pixels with the colour of the line. Add a couple of lines in your code here

# Draw Contours
blank_mask = np.zeros((thresh.shape[0],thresh.shape[1],3), np.uint8)
cv2.drawContours(blank_mask, contours, -1, (0, 255, 0), 1)
contours_idx = blank_mask[...,1] == 255

# Define lines coordinates
line1 = [x1, y1, x2, y2]
line2 = [x1, y1, x2, y2]
line3 = [x1, y1, x2, y2]

# Draw Lines over Contours
cv2.line(blank_mask, (line1[0], line1[1]), (line1[2], line1[3]), (255, 0, 0), thickness=1)
cv2.line(blank_mask, (line2[0], line2[1]), (line2[2], line2[3]), (255, 0, 0), thickness=1)
cv2.line(blank_mask, (line3[0], line3[1]), (line3[2], line3[3]), (255, 0, 0), thickness=1)
lines_idx = blank_mask[...,0] == 255

And then

overlap = np.where(contours_idx * lines_idx)

Which will give you something similar to the following (I had to guess your line coordinates and image resize shape, so I may be a bit off)

(array([ 90, 110, 110, 140, 140], dtype=int64), array([ 80,  40, 141,  27, 156], dtype=int64))

And if you want them in tuples of pixel coordinates

list(zip(*overlap))

Edit: For a more general solution where the colour of the contours/lines is in more than one plane, you can check for the full colour of each pixel after each draw. For example

# Change these
contours_idx = blank_mask[...,1] == 255
lines_idx = blank_mask[...,0] == 255

# To this
contours_idx = np.all(blank_mask == (0, 255, 0), axis=-1)
lines_idx = np.all(blank_mask == (255, 0, 0), axis=-1)
Answered By: Reti43
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.