Click here to Skip to main content
15,881,089 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more: , +
yRBW2 — Postimages[^]
hi, at the first, please open link and see (image) that is on top of question

i have only one simple question

as you see in image , there are few lines in image, my code find intersection points of lines

i want to know how we can select and drag these points (intersection points) by mouse or by arrow keys (change position of each point manually)?

you can download my project (lower than 1mb) at:Upload files for free - file1.zip - ufile.io[^]

What I have tried:

Python
<pre>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 10-Sep-21 5:02am
v7

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