Click here to Skip to main content
15,889,335 members
Please Sign up or sign in to vote.
1.00/5 (3 votes)
See more:
hi guys
i am very new in python
and i am trying to edit this code in python and image proccessing open cv
it is about soccer offside
i could change some parts very goods as i want

you can download my project (lower than 1mb) at:
[^]

after open the project folder
please open and run this file : offside_automatic.py
after run
please Click in a place in image then press enter
then again Click in other place in image then press enter
you will see 2 lines for offside
i have 4 request that if anybody can solve even of of it can big help to me
thanks

1- you can see intersection points in image that there are green circles on them, how can i drag and drop that circles ? that i be able to change their position to correct places

2- when you click on foot of players on first time , you will see a little red circle, it is ok , but if i had a mistake , how can i delete that red circle and draw it again in a new place?

3- after that i click on image and show that little red circle
, i must (press enter button) then i can click again for second red circle , how can i chance code that , i don't need to press enter button??? , and i can continue to press second time without need to press enter button

4-when i run the app , there is many lines have drawn in image on the white lines of field , how can i hidden and show again line with a key???

thanks to anyone , that reply to ,my question

What I have tried:

import cv2
import math
import utils
import numpy as np
from itertools import permutations



def findBestHomography():
    # Loop through all the possible permutations of 4 points in the image
    all_img_pts = [np.array(i, dtype=float) for i in intersections]
    for img_pts in permutations(intersections, 4):
        # Optimization: check if polygon is convex and clockwise
        if not utils.isConvex(img_pts) or not utils.isClockwise(img_pts):
            continue

        # Loop through all the possible permutations of 4 points in the reference
        for ref_points in permutations(utils.reference_points_right, 4):
            # Optimization: check if polygon is convex and clockwise
            if not utils.isConvex(img_pts) or not utils.isClockwise(img_pts):
                continue

            # Convert to np.ndarray of np.ndarray of float64
            img_pts = [np.array(i, dtype=float) for i in img_pts]
            img_pts = np.array(img_pts)
            ref_points = np.array(ref_points)
            
            # Calculate homography
            h, status = cv2.findHomography(img_pts, ref_points)
            h_inv = None
            if h is None:
                continue
            try:
                h_inv = np.linalg.inv(h)
            except:
                continue

            # Check if at least one other image point matches one other reference point
            for test_img_pt in all_img_pts:
                if not test_img_pt in img_pts:
                    for test_ref_pt in utils.reference_points_right:
                        if not list(test_ref_pt) in ref_points.tolist():
                            # Apply homography to reference test point
                            test_img_in_ref = cv2.perspectiveTransform(test_img_pt.reshape(1, 1, -1), h)[0][0]
                            # Check if it matches the image test point with an error of at most 2m
                            distance = np.linalg.norm(test_img_in_ref - test_ref_pt)
                            if distance < 2:
                                print(test_ref_pt)
                                print(ref_points)
                                print(test_img_pt)
                                print(img_pts)
                                print(test_img_in_ref)
                                print(distance)
                                print('-------------------------------------')
                                applyHomographyLine(img, h, h_inv)
                                return


def applyHomographyLine(img, h, h_inv):
    # Get offside player point (field image)
    print('Click on the offside player and then press [ENTER]')
    player_im = utils.get_points(img, 1)[0]
    player_imm = utils.get_points(img, 1)[0]

    #print(player_im)

    # Get corresponding offside player point in real world
    player_rw = cv2.perspectiveTransform(player_im.reshape(1, 1, -1), h)[0][0]
    player_rww = cv2.perspectiveTransform(player_imm.reshape(1, 1, -1), h)[0][0]

    #print(player_rw)

    # Get the two line points in the real world line (same x, y is the field bounds)
    line_point_1_rw = player_rw.copy()
    line_point_1_rw[1] = 0
    line_point_2_rw = player_rw.copy()
    line_point_2_rw[1] = 67
    line_point_3_rw = player_rww.copy()
    line_point_3_rw[1] = 0
    line_point_4_rw = player_rww.copy()
    line_point_4_rw[1] = 67
    #print(line_point_1_rw)
    #print(line_point_2_rw)

    # Get corresponding second point in the image
    line_point_1_im = cv2.perspectiveTransform(line_point_1_rw.reshape(1, 1, -1), h_inv)[0][0]
    line_point_2_im = cv2.perspectiveTransform(line_point_2_rw.reshape(1, 1, -1), h_inv)[0][0]
    line_point_3_im = cv2.perspectiveTransform(line_point_3_rw.reshape(1, 1, -1), h_inv)[0][0]
    line_point_4_im = cv2.perspectiveTransform(line_point_4_rw.reshape(1, 1, -1), h_inv)[0][0]
    #print(line_point_1_im)
    #print(line_point_2_im)

    # Draw line
    height, width, channels = img.shape
    blank_image = np.zeros((height,width,3), np.uint8)
    cv2.line(blank_image, tuple(line_point_1_im.astype(int)), tuple(line_point_2_im.astype(int)), (0,0,255), 1, cv2.LINE_AA)
    cv2.line(blank_image, tuple(line_point_3_im.astype(int)), tuple(line_point_4_im.astype(int)), (255,255,0), 1, cv2.LINE_AA)
    img = utils.blend_overlay_with_field(img,blank_image,0.5)

    cv2.imshow("Image", img)
    cv2.waitKey(0)




if __name__ == '__main__':
    debug = True

    img = cv2.imread('./football1.jpg')
    field = utils.GetFieldLayer(img)
    # cv2.imshow("Field Layer", field)
    field = cv2.GaussianBlur(field, (3, 3), cv2.BORDER_DEFAULT)
    edges = cv2.Canny(field, 100, 300)
    lines = cv2.HoughLines(edges, 1, math.radians(1.7), 150, None, 0, 0)

    lns = []

    if lines is not None:
        for i in range(0, len(lines)):
            rho = lines[i][0][0]
            theta = lines[i][0][1]
            a = math.cos(theta)
            b = math.sin(theta)
            x0 = a * rho
            y0 = b * rho
            pt1 = (int(x0 + 1000 * (-b)), int(y0 + 1000 * (a)))
            pt2 = (int(x0 - 1000 * (-b)), int(y0 - 1000 * (a)))
            lns.append(utils.Line(pt1, pt2))

    # Calculate intersection points
    intersections = []
    for i in range(0, len(lns)):
        for j in range(i + 1, len(lns)):
            point = lns[i].intersection(lns[j])
            if not point is None:
                intersections.append(point)
        if debug:
         cv2.line(img, lns[i].pt1, lns[i].pt2, (0, 0, 255), 1)


    # Cleanup similar points and points outside of the image
    i = 0
    while i < len(intersections):

        # Check if outside of image
        xi,yi = intersections[i]
        sy,sx,_ = img.shape
        if xi < 0 or yi < 0 or xi > sx or yi > sy:
            del intersections[i]
            continue

        # Check if similar 
        j = i+1
        while j < len(intersections):
            distance = np.linalg.norm(list(x-y for x,y in zip(intersections[i],intersections[j])))
            if distance < 20:
                del intersections[j]
                continue
            j += 1
        i += 1
    # Draw points
    if debug:
        for point in intersections:
            cv2.circle(img, point, 10, (0, 255, 0))

 
   # Homography
    if len(intersections) < 4:
       raise Exception('Not enough points were detected for a homography')

    findBestHomography() 
Posted
Updated 6-Sep-21 6:34am
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900