def homePlate_transform(frame, home): # obtain a square in a consistent points order square = get_home_square(home) # compute the destination points of the perspective transform square home_width = params.transform_resolution[1] * params.size_homePercenct x14 = params.transform_resolution[0] - params.transform_resolution[0] * .01 x23 = x14 - home_width y12 = (params.transform_resolution[1] + home_width) / 2. y34 = y12 - home_width dst = np.array([[x14, y12], [x23, y12], [x23, y34], [x14, y34]], dtype="float32") # compute the perspective transform matrix PTM = cv2.getPerspectiveTransform(square, dst) # find the new home plate contour homePlate_cnt = np.array([[x14, params.transform_resolution[1] / 2.], [x23 + home_width / 2., y12], [x23, y12], [x23, y34], [x23 + home_width / 2., y34]]) if params.debugging: warped = cv2.warpPerspective(frame, PTM, params.transform_resolution) cnt = square.reshape((4, 1, 2)) show_contours([cnt.astype('int32')], frame, 'Square') cv2.imshow('Warped', warped) cv2.waitKey(0) cv2.destroyWindow('Warped') cv2.destroyWindow('Square') print("TRANSFORMING FRAME DONE!!!\n") # return the perspective transform matrix return PTM, homePlate_cnt
def filter_by_area(frame, contours): filter_contours = [] frame_size = frame.shape[0] * frame.shape[1] for cnt in contours: cnt_area = cv2.contourArea(cnt) percent_area = 100 * cnt_area / frame_size if percent_area > params.max_percentArea or percent_area < params.min_percentArea: if params.debugging: print("discarded by area") else: filter_contours.append(cnt) if params.debugging: print("carded by area") if params.debugging: show_contours([cnt], frame, 'working cnt in filter by area') cv2.waitKey(0) if params.debugging: print('\nFilter By Area. DONE!!!\n') cv2.destroyWindow('working cnt in filter by area') cv2.destroyWindow('all contours') show_contours(filter_contours, frame, 'filters contours by area') cv2.waitKey(0) return np.array(filter_contours)
def filter_by_angles(frame, contours): filter_contours = [] for cnt in contours: angles = get_angles_sorted_by_magnitude(cnt) if np.allclose(angles[:3], [90] * 3, 0, params.diff_rectAngles) and np.allclose( angles[3:], [135] * 2, 0, params.diff_maxAngles): filter_contours.append(cnt) if params.debugging: print("carded by angles") elif params.debugging: print("discarded by angles") print("SORTED ANGLES") print(angles) if params.debugging: show_contours([cnt.astype('int32')], frame, 'working cnt in filter by angles') filter_contours = np.array(filter_contours) if params.debugging: print('\nFilter By Angles. DONE!!!\n') cv2.destroyWindow('working cnt in filter by angles') cv2.destroyWindow('filters contours by sides ratio') show_contours(filter_contours.astype('int32'), frame, 'filters contours by angles') cv2.waitKey(0) return filter_contours
def get_homes(frame): thresh = cv2.adaptiveThreshold(frame, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, params.thresh_blockSize, 7) if params.debugging: cv2.imshow('Thresh', thresh) contours_img = thresh.copy() contours, _ = cv2.findContours(contours_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) if params.debugging: show_contours(contours, frame, 'all contours') filters = [ filter_by_area, filter_by_sidesNumber, filter_by_sidesRatio, filter_by_angles ] homes = filter_by(frame, filters, contours) if params.debugging: cv2.destroyWindow('Thresh') cv2.destroyWindow('filters contours by angles') print("DETECTING HOMES DONE!!!\n") show_contours(homes.astype('int32'), frame, 'homes') cv2.waitKey(0) cv2.destroyWindow('homes') homes = [HomePlate(home) for home in homes] return homes
def filter_by_radius(frame, contours, frame_number): balls = [] frame_size = frame.shape[0] * frame.shape[1] for cnt in contours: if params.aproxContour == 0: x, y, w, h = cv2.boundingRect(cnt) radius = w / 2. if w < h else h / 2. # center = np.array([x+w/2., y+h/2.]) center = np.array([x + w - radius, y + h - radius]) elif params.aproxContour == 1: rect = cv2.minAreaRect(cnt) # box = cv2.boxPoints(rect) # box = np.int0(box) elif params.aproxContour == 2: center, radius = cv2.minEnclosingCircle(cnt) radiusPercent = 100 * radius / frame_size ball = Ball(center, radius, frame_number) if radiusPercent > params.max_radiusPercent or radiusPercent < params.min_radiusPercent: if params.debugging: print("discarded by radius ", radiusPercent) elif center[0] > params.home_begin: if params.debugging: print("discarded by the ball is in the end of the image") else: balls.append(ball) if params.debugging: print("carded by radius") if params.debugging: if params.aproxContour == 0: preview = frame.copy() cv2.rectangle(preview, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.imshow('rect aprox', preview) show_contours([cnt], frame, 'working cnt in filter by radius') draw_ball(ball, frame, 'Enclosing circle of working cnt in filter by radius') cv2.waitKey(0) if params.debugging: if params.aproxContour == 0: cv2.destroyWindow('rect aprox') cv2.destroyWindow('working cnt in filter by radius') cv2.destroyWindow( 'Enclosing circle of working cnt in filter by radius') cv2.destroyWindow('all contours') draw_balls(balls, frame, 'filters balls by radius') cv2.waitKey(0) return np.array(balls)
def filter_by_sidesRatio(frame, contours): filter_contours = [] for cnt in contours: lines = get_lines_sorted_by_dist(cnt) min_dist = int(((lines[0][0][0] - lines[0][1][0])**2 + (lines[0][0][1] - lines[0][1][1])**2)**.5) winSize = min_dist // 2 if min_dist % 4 != 0 else min_dist // 2 - 1 refined_corners = cnt.astype('float32') refining_corners(frame, refined_corners, (winSize, winSize)) refined_lines = get_lines_sorted_by_dist(refined_corners) dist = get_dist(refined_lines) min_diff = abs(dist[0] - dist[1]) percent_min_sides = 100 * min_diff / dist[ 1] # find the percent with max distance to minimize the percentage max_diff = abs(dist[2] - dist[3]) percent_middel_sides = 100 * max_diff / dist[ 3] # find the percent with max distance to minimize the percentage if percent_min_sides <= params.percentSideRatio and percent_middel_sides <= params.percentSideRatio: # filter by percent between distances filter_contours.append(refined_corners) if params.debugging: print('carded by sides ratio') elif params.debugging: print("discarded by sides ratio") print("SORTED DISTANCES") print(dist) print("MIN_SIDES PERCENT: ", percent_min_sides) print("MIDDEL_SIDES PERCENT: ", percent_middel_sides) if params.debugging: show_contours([cnt], frame, 'working cnt in filter by sides ratio') draw_home_lines(lines, frame, 'lines') draw_home_lines(refined_lines, frame, 'refined_corners') cv2.waitKey(0) filter_contours = np.array(filter_contours) if params.debugging: print('\nFilter By Sides Ratio. DONE!!!\n') cv2.destroyWindow('working cnt in filter by sides ratio') cv2.destroyWindow('lines') cv2.destroyWindow('refined_corners') cv2.destroyWindow('filters contours by sides number') show_contours(filter_contours.astype('int32'), frame, 'filters contours by sides ratio') cv2.waitKey(0) return filter_contours
def get_balls(frame, frame_number): mask = get_mask(frame) contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) if params.debugging: show_contours(contours, frame, 'all contours') filters = [filter_by_radius] balls = filter_by(frame, filters, contours, frame_number) if params.debugging: cv2.destroyWindow('filters balls by radius') if params.useKmeans: cv2.destroyWindow('Kmeans') else: cv2.destroyWindow('Background Subtractor') print("\nGETTING BALLS DONE!!!\n") draw_balls(balls, frame, 'balls') cv2.waitKey(0) cv2.destroyWindow('balls') return balls
def filter_by_sidesNumber(frame, contours): filter_contours = [] for cnt in contours: hull = cv2.convexHull(cnt) if params.useHull: epsilon = 0.03 * cv2.arcLength(hull, True) cnt_approx = cv2.approxPolyDP(hull, epsilon, True) else: epsilon = 0.03 * cv2.arcLength(cnt, True) cnt_approx = cv2.approxPolyDP(cnt, epsilon, True) if len(cnt_approx) == params.numberOfSizes: filter_contours.append(cnt_approx) if params.debugging: print("carded by sides number") elif params.debugging: print("discarded by sides number: ", len(cnt_approx), " sides") if params.debugging: show_contours([cnt], frame, 'working cnt in filter by sides') show_contours([hull], frame, "Hull") show_contours([cnt_approx], frame, 'approx of working cnt in filter by sides') cv2.waitKey(0) if params.debugging: print('\nFilter By Sides Number. DONE!!!\n') cv2.destroyWindow('working cnt in filter by sides') cv2.destroyWindow('Hull') cv2.destroyWindow('approx of working cnt in filter by sides') cv2.destroyWindow('filters contours by area') show_contours(filter_contours, frame, 'filters contours by sides number') cv2.waitKey(0) return np.array(filter_contours)