How to find intersection points between lines and contours

Viewed 573

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

1 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)
Related