简体   繁体   中英

How to detect lines in a football field using OpenCV

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

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 边缘检测

And better than this for Hough Lines transform: 在此处输入图像描述

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?

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: 在此处输入图像描述

Play with arguments for getting desired result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM