美式足球场完整标线检测及单应性变换场域校正技术问询
美式足球场标线检测与鸟瞰视角变换问题
问题背景
我正尝试检测美式足球场的完整标线,实现球员定位并通过**单应性变换(homography)**将场域转换为鸟瞰视角。目前使用Python与OpenCV开发,但无法获取全场完整标线。
输入图像

当前检测结果
参考相关方案后,仅得到如下结果:
当前结果已接近目标,但希望每条水平标线都能以单条蓝色线条贯穿全场。
现有处理流程
- 掩码提取场地白色区域
- 使用Canny边缘检测:
canny = cv2.Canny(img_mask, 50, 150, apertureSize=3)
- 从Canny结果中提取霍夫线:
lines_p = cv2.HoughLinesP(canny, 1, np.pi / 180, 100, None, 0, 20)
- 延伸并合并相近线条得到上述结果
相关代码
def extend_lines(lines, extension_length=20): """ Extend short line segments by a specified length. Parameters: - lines: List of line segments in the format ((x1, y1), (x2, y2)). - extension_length: Length by which to extend the lines. Returns: - List of extended line segments. """ extended_lines = [] for line in lines: print(line) x1, y1, x2, y2 = line[0] # Calculate the vector representing the line segment dx, dy = x2 - x1, y2 - y1 # Normalize the vector length = np.sqrt(dx**2 + dy**2) if length > 0: dx /= length dy /= length # Extend the line segment by the specified length x1_extended = int(x1 - extension_length * dx) y1_extended = int(y1 - extension_length * dy) x2_extended = int(x2 + extension_length * dx) y2_extended = int(y2 + extension_length * dy) extended_lines.append([[x1_extended, y1_extended, x2_extended, y2_extended]]) else: extended_lines.append(line) for i in reversed(range(len(extended_lines))): line = extended_lines[i] print(line[0]) length = np.sqrt((line[0][2] - line[0][0])**2 + (line[0][3] - line[0][1])**2) if length < 150: del extended_lines[i] return extended_lines def merge_close_lines(lines, epsilon=50, min_samples=2): """ Merge lines that are close to each other. Parameters: - lines: List of line segments in the format ((x1, y1), (x2, y2)). - epsilon: Maximum distance to consider for merging lines. - min_samples: Minimum number of samples required to form a cluster. Returns: - List of merged line segments. """ points = np.array([[(line[0][0] + line[0][2]) / 2, (line[0][1] + line[0][3]) / 2] for line in lines]) # Apply DBSCAN clustering db = DBSCAN(eps=epsilon, min_samples=min_samples).fit(points) labels = db.labels_ # Group lines by cluster label grouped_lines = {} for i, label in enumerate(labels): if label in grouped_lines: grouped_lines[label].append(lines[i]) else: grouped_lines[label] = [lines[i]] # Fit a line to each cluster merged_lines = [] for label, lines_in_cluster in grouped_lines.items(): merged_line = find_longest_line(lines_in_cluster) merged_lines.append(merged_line) return merged_lines def find_longest_line(lines): longest_line = None max_length = 0 for line in lines: x1, y1, x2, y2 = line[0] length = np.sqrt((x2 - x1)**2 + (y2 - y1)**2) if length > max_length: max_length = length longest_line = line return longest_line
需求
寻求更稳定准确的标线检测方案,或基于现有结果实现场域变换的方法。
内容的提问来源于stack exchange,提问作者flyingchicken
相关产品推荐
相关产品推荐

