hi guys
The below code segment enables
user to select 4 corners of penalty area with right click
then he can select a place in field to draw a line of offside, same with right click
then close with press enter with my app user should select 4 corners of penalty area (manually)
I need a correct suggest to app do it automatically (find points of 4 corners of penalty area) (I think it need to find intersection points of white Lines)
you can find the image 35.jpg at here
thanks
this is code
import cv2
import numpy as np
pts_src = np.array(
[
[87.5, 12.84], # Top Left
[104, 12.84], # Top Right
[104, 53.16], # Bottom Right
[87.5, 53.16] # Bottom Left
], dtype=float
)
def mouse_handler(event, x, y, flags, data):
if event == cv2.EVENT_RBUTTONDOWN:
if len(data['points']) < data['max_points']:
cv2.circle(data['im'], (x, y), 1, (0, 0, 255), 2, 5)
cv2.imshow("Image", data['im'])
data['points'].append([x, y])
def get_points(im, max_points):
# Set up data to send to mouse handler
data = {}
data['im'] = im.copy()
data['points'] = []
data['max_points'] = max_points
# Set the callback function for any mouse event
cv2.imshow("Image", im)
cv2.setMouseCallback("Image", mouse_handler, data)
cv2.waitKey(0)
cv2.setMouseCallback("Image", lambda *args: None)
# Convert array to np.array
points = np.vstack(data['points']).astype(float)
return points
def blend_overlay_with_field(src_img, overlay, transparency):
hsv = cv2.cvtColor(src_img, code=cv2.COLOR_BGR2HSV)
# green range
lower_green = np.array([35, 10, 60])
upper_green = np.array([65, 255, 255])
# layer masks
field_mask = cv2.inRange(hsv, lower_green, upper_green)
player_mask = cv2.bitwise_not(field_mask)
# player_mask = cv2.morphologyEx(player_mask, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)))
# extract layers from original image
field_layer = cv2.bitwise_and(src_img, src_img, mask=field_mask)
player_layer = cv2.bitwise_and(src_img, src_img, mask=player_mask)
# creates line that is blank where the players are
overlay_layer = cv2.bitwise_and(overlay, overlay, mask=field_mask)
# overlay_layer = cv2.GaussianBlur(overlay_layer,(3,3),cv2.BORDER_DEFAULT)
field_layer = cv2.addWeighted(field_layer, 1, overlay_layer, transparency, 0)
final = field_layer + player_layer
return final
if __name__ == '__main__':
im_dst = cv2.imread('images/35.jpg')
clean_img = im_dst.copy()
# Get four corners of the penalty area
print('Click on the four corners of the penalty area and then press [ENTER]')
pts_dst = get_points(im_dst, 4)
print(pts_dst)
# Calculate Homography between source and destination points
h, status = cv2.findHomography(pts_src, pts_dst)
h_inv = np.linalg.inv(h)
# print(h)
# Get offside player point (field image)
print('Click on the offside player and then press [ENTER]')
player_im = get_points(im_dst, 1)[0]
print(player_im)
# Get corresponding offside player point in real world
player_rw = cv2.perspectiveTransform(player_im.reshape(1, 1, -1), h_inv)[0][0]
# print(player_rw)
# print(player_rww)
# 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
# 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)[0][0]
line_point_2_im = cv2.perspectiveTransform(line_point_2_rw.reshape(1, 1, -1), h)[0][0]
# print(line_point_1_im)
# print(line_point_2_im)
# Draw line
height, width, channels = clean_img.shape
blank_image = np.zeros((height, width, 3), np.uint8)
overlay_img = blank_image
cv2.line(overlay_img, tuple(line_point_1_im.astype(int)), tuple(line_point_2_im.astype(int)),
(255, 0, 255), 2, cv2.LINE_AA)
final = blend_overlay_with_field(clean_img, overlay_img, 0.5)
# Display image.
cv2.imshow("Image", final)
cv2.waitKey(0)