1
votes

I am trying to detect lines in a football field video, but unfortunately I can't get it to work with my pictures. Original picture

I am using Canny to detect edges, then Hough Lines transform to get the lines and I think I can't find the right parameters for my usage.

I've tried adding homography (closing) to smooth edges detection, resizing the picture to improve detection accuracy, adjust the white balance, adding gaussian blur but I can't get something cleaner than this for Canny edges detection: Canny edges detection

And better than this for Hough Lines transform: enter image description here

imgsrc = cv2.imread("image.png")

# Resize to improve detection accuracy
t = int(img.shape[1] * 1.6)
img = imutils.resize(imgsrc, width=t)

# Apply gaussian blur
kernel_size = 3
img = cv2.GaussianBlur(img, (kernel_size, kernel_size), 0)

# Convert to grayscale
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Initialize morph-kernel, apply CLOSE before Canny to improve edges detection
kernel0 = np.ones((9,27), np.uint8)
img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel0)

# Detect edges
low_threshold = 5
high_threshold = 50
edges = cv2.Canny(img, low_threshold, high_threshold)

# Initialize morph-kerne, apply CLOSE after Canny to merge edges
kernel2 = np.ones((8,24), np.uint8)
edges = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel2)

# Hough Lines params
rho = 1  # distance resolution in pixels of the Hough grid
theta = np.pi / 180  # angular resolution in radians of the Hough grid
# minimum number of votes (intersections in Hough grid cell)
threshold = 30
min_line_length = 50  # minimum number of pixels making up a line
max_line_gap = 40  # maximum gap in pixels between connectable line segments

# Run Hough on edge detected image
lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]), min_line_length, max_line_gap)

output = np.copy(imgsrc) * 0  # creating a blank to draw lines on
for line in lines:
    for x1, y1, x2, y2 in line:
        cv2.line(output, (int(x1), int(y1)), (int(x2), int(y2)), (255, 255, 255), thickness)

Do you have any idea how I can improve my line detection, and get only a few lines in the end?

1
I dont think that morphological functions are available for this task. My suggestion is that you should use advanced algorithms(yolo,rcnn etc.)Yunus Temurlenk
Thank you for your help, however we are asked to provide a simpler image processing algorithm first, that does not involve machine learning...geckoflume
since you have a coloured image, have you though of clustering your colours into 2 or 3 classes and than use edge detection ? Could might help to create a basic difference see: docs.opencv.org/master/d1/d5c/tutorial_py_kmeans_opencv.htmlt2solve

1 Answers

1
votes

Here's the solution code in Python:

import cv2
from matplotlib import pyplot as plt
import numpy

im = cv2.imread("foot.png")
B = im[:,:,2]
Y = 255-B

thresh = cv2.adaptiveThreshold(Y,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
            cv2.THRESH_BINARY_INV,35,5)

contours, hierarchy = cv2.findContours(thresh,  
    cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) 

x=[]
for i in range(0, len(contours)):
    if cv2.contourArea(contours[i]) > 100:
        x.append(contours[i])
cv2.drawContours(im, x, -1, (255,0,0), 2) 

plt.imshow(im)

Output: enter image description here

Play with arguments for getting desired result.