检测网球场线截距

时间:2019-04-03 13:29:33

标签: python opencv computer-vision

我正在尝试改进代码以查找网球场线截距,以便可以找到法院不同象限的边界。

输入图像 This is the tennis court image I am trying to analyze

输出图像 This is the final result

我首先通过找到图像中的白色像素,然后通过一些预处理(例如高斯模糊)应用Canny边缘检测来实现这一点。然后将canny edge输出进行扩展,以帮助准备好进行hough线检测。

然后获取输出的高音行,我使用了github用户ideamanman42的Bentley–Ottmann algorithm的python实现来查找高音行截距。

这似乎工作得很好,但是我正在努力调整系统以找到最后4个拦截点。如果有人可以给我建议以改善或调整此实施方式,甚至提出一些想法,以更好地解决法院边界问题,我将不胜感激。

# import the necessary packages
import numpy as np
import argparse
import cv2
import scipy.ndimage as ndi
import  poly_point_isect as bot

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", help = "path to the image")
args = vars(ap.parse_args())

# load the image
image = cv2.imread(args["image"])

# define the list of boundaries
boundaries = [
    ([180, 180, 100], [255, 255, 255])
]

# loop over the boundaries
for (lower, upper) in boundaries:
    # create NumPy arrays from the boundaries
    lower = np.array(lower, dtype = "uint8")
    upper = np.array(upper, dtype = "uint8")

    # find the colors within the specified boundaries and apply
    # the mask
    mask = cv2.inRange(image, lower, upper)
    output = cv2.bitwise_and(image, image, mask = mask)

    # show the images
    cv2.imshow("images", np.hstack([image, output]))
    cv2.waitKey(0)

gray = cv2.cvtColor(output,cv2.COLOR_BGR2GRAY)

kernel_size = 5
blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0)

low_threshold = 10
high_threshold = 200
edges = cv2.Canny(gray, low_threshold, high_threshold)
dilated = cv2.dilate(edges, np.ones((2,2), dtype=np.uint8))

cv2.imshow('dilated.png', dilated)
cv2.waitKey(0)

rho = 1  # distance resolution in pixels of the Hough grid
theta = np.pi / 180  # angular resolution in radians of the Hough grid
threshold = 10 # minimum number of votes (intersections in Hough grid cell)
min_line_length = 40  # minimum number of pixels making up a line
max_line_gap = 5  # maximum gap in pixels between connectable line segments
line_image = np.copy(output) * 0  # creating a blank to draw lines on

# Run Hough on edge detected image
# Output "lines" is an array containing endpoints of detected line segments

lines = cv2.HoughLinesP(dilated, rho, theta, threshold, np.array([]), min_line_length, max_line_gap)

points = []
for line in lines:
    for x1, y1, x2, y2 in line:
        points.append(((x1 + 0.0, y1 + 0.0), (x2 + 0.0, y2 + 0.0)))
        cv2.line(line_image, (x1, y1), (x2, y2), (255, 0, 0), 5)        

cv2.imshow('houghlines.png', line_image)
cv2.waitKey(0)

lines_edges = cv2.addWeighted(output, 0.8, line_image, 1, 0)
print(lines_edges.shape)

intersections = bot.isect_segments(points)
print(intersections)

for idx, inter in enumerate(intersections):
    a, b = inter
    match = 0
    for other_inter in intersections[idx:]:
        c, d = other_inter
        if abs(c-a) < 8 and abs(d-b) < 8:
            match = 1
            if other_inter in intersections:
                intersections.remove(other_inter)
                intersections[idx] = ((c+a)/2, (d+b)/2)

    if match == 0:
        intersections.remove(inter)

for inter in intersections:
    a, b = inter
    for i in range(6):
        for j in range(6):
            lines_edges[int(b) + i, int(a) + j] = [0, 0, 255]

# Show the result
cv2.imshow('line_intersections.png', lines_edges)
cv2.imwrite('line_intersections.png', lines_edges)
cv2.waitKey(0)

1 个答案:

答案 0 :(得分:0)

这是我的解决方案,使用了不同的方法。我使用哈里斯拐角检测器来检测拐角。只是匆忙地调整了参数,请随时使用它们。 Here是OpenCV的教程。

我使用OpenCV Wrapper library获得一些更简单的OpenCV代码。如果您不想要它,应该很容易翻译。

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

        <com.orange.es.orangetv.views.drawer.CustomDrawer
            android:id="@+id/navigation_drawer"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <android.support.design.widget.CoordinatorLayout
                    android:id="@+id/coordinator"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_above="@id/cast_mini_controller"
                    android:background="@color/base_blue">

                    <com.orange.es.orangetv.views.CustomAppBarLayout
                        android:id="@+id/app_bar_layout"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:background="@color/base_gray">

                            <android.support.design.widget.CollapsingToolbarLayout
                                android:id="@+id/collapsing_toolbar"
                                android:layout_width="match_parent"
                                android:layout_height="match_parent"
                                app:layout_scrollFlags="scroll"
                                app:toolbarId="@+id/toolbar">

                                <fragment
                                    android:id="@+id/slideshow_fragment"
                                    class="com.orange.es.orangetv.screens.fragments.slideshow.SlideshowFragment"
                                    android:layout_width="match_parent"
                                    android:layout_height="match_parent" />

                                <android.support.v7.widget.Toolbar
                                    android:id="@+id/toolbar"
                                    android:layout_width="match_parent"
                                    android:layout_height="@dimen/topmenu_height"
                                    android:background="@color/color_transparent"
                                    app:layout_collapseMode="pin" />

                            </android.support.design.widget.CollapsingToolbarLayout>

                    </com.orange.es.orangetv.views.CustomAppBarLayout>

                    <fragment
                        android:id="@+id/flatten_items_fragment"
                        class="com.orange.es.orangetv.screens.fragments.section_rows.FlattenRowsFragment"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="@dimen/column_bottom_edge_height"
                        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

                    <include layout="@layout/loader_view" />

                </android.support.design.widget.CoordinatorLayout>

                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar_topmenu"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/topmenu_height"
                    android:background="@color/color_transparent"
                    android:paddingLeft="@dimen/toolbar_padding"
                    android:paddingRight="@dimen/toolbar_padding"
                    android:theme="@style/ToolbarOverlay"
                    app:contentInsetEnd="@dimen/toolbar_padding"
                    app:contentInsetLeft="@dimen/toolbar_padding"
                    app:contentInsetRight="@dimen/toolbar_padding"
                    app:contentInsetStart="@dimen/toolbar_padding"
                    app:elevation="@dimen/toolbar_elevation">

                    <include
                        layout="@layout/menu_layout"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentStart="true"
                        android:layout_alignParentLeft="true"
                        android:layout_alignParentTop="true" />

                </android.support.v7.widget.Toolbar>

                <fragment
                    android:id="@+id/cast_mini_controller"
                    class="com.aspiro.tv.MoonWalker_library.video.cast.CustomMiniControllerFragment"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:visibility="gone"
                    app:castShowImageThumbnail="true" />

            </RelativeLayout>

            <fragment
                android:id="@+id/drawer_fragment"
                class="com.orange.es.orangetv.screens.fragments.drawer.DrawerFragment"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_gravity="start"
                android:background="@color/colorWhite" />

        </com.orange.es.orangetv.views.drawer.CustomDrawer>

        <include layout="@layout/layout_container" />
    </FrameLayout>
</layout>

结果:

enter image description here

披露:我是OpenCV Wrapper的作者。