def tile_images(img_width, img_height, num_width, num_height, images, channels=3): w = img_width * num_width h = img_height * num_height image = cv.cvCreateImage(cv.cvSize(int(w), int(h)), 8, channels) cv.cvSet(image, cv.cvScalar(255,255,255)) while len(images) > 0: try: for y in range(int(num_height)): for x in range(int(num_width)): small_tile = images.pop() img_x = x * img_width img_y = y * img_height cropped = cv.cvGetSubRect(image, cv.cvRect(img_x, img_y, img_width,img_height)) cv.cvCopy(small_tile, cropped) except exceptions.IndexError, e: break
def tile_images(img_width, img_height, num_width, num_height, images, channels=3): w = img_width * num_width h = img_height * num_height image = cv.cvCreateImage(cv.cvSize(int(w), int(h)), 8, channels) cv.cvSet(image, cv.cvScalar(255, 255, 255)) while len(images) > 0: try: for y in range(int(num_height)): for x in range(int(num_width)): small_tile = images.pop() img_x = x * img_width img_y = y * img_height cropped = cv.cvGetSubRect( image, cv.cvRect(img_x, img_y, img_width, img_height)) cv.cvCopy(small_tile, cropped) except exceptions.IndexError, e: break
def text(image, x, y, a_string): font = cv.cvInitFont(CV_FONT_HERSHEY_SIMPLEX, .3, .3) cv.cvPutText(image, a_string, cv.cvPoint(x, y), font, cv.cvScalar(0, 0, 0)) cv.cvPutText(image, a_string, cv.cvPoint(x + 1, y + 1), font, cv.cvScalar(255, 255, 255))
def main(): """Run the whole shiz.""" global tmpl_ball, pocket_templates, pocket_markers, last_best_cueball, last_confirmed_cueball, CURRENT_FRAME, out_file start_time = datetime.datetime.now() # Open output files out_file = open(here("confirmed_cueballs.txt"), 'w') # Initialize pygame pygame.init() pygame.display.set_caption("Snooker - main info window") window = pygame.display.set_mode((704, 400)) # Load and initialize template images tmpl_ball = cvLoadImage(BALL_TMPL, CV_LOAD_IMAGE_COLOR) if not tmpl_ball: raise Exception("Failed to load ball template image") # Load pocket templates, find marker pixel in template and remember it for pocket in ['tl', 'tr', 'bl', 'br']: pocket_tmpl = cvLoadImage(globals()['POCKET_%s_TMPL' % pocket.upper()], CV_LOAD_IMAGE_COLOR) if not pocket_tmpl: raise Exception("Failed to load pocket '%s' template" % pocket) pocket_templates[pocket] = pocket_tmpl pocket_markers[pocket] = findpixel(pocket_tmpl, cvScalar(255, 0, 255)) if pocket_markers[pocket]: if DEBUG: print("Found marker for pocket %s at %d:%d" % (pocket.upper(), pocket_markers[pocket].x, pocket_markers[pocket].y)) stream = pyffmpeg.VideoStream() stream.open(VIDEO_FILE) fps = stream.tv.get_fps() duration_f = stream.tv.duration() start_frame = int(START*fps) end_frame = int(END*fps) interval = int(INTERVAL*fps) length = float(end_frame-start_frame)/float(fps) # Seconds i = start_frame while i < end_frame: CURRENT_FRAME = i # Calculate info about the total progress and display it percentage = float(i-start_frame)/float(end_frame-start_frame)*100.0 estimated_length = 0 if i > start_frame: estimated_length = float(total_seconds((datetime.datetime.now()-start_time))) / percentage * 100.0 print("Frame #%d (%d-%d) %.1f%%" % (i, start_frame, end_frame, percentage)) pygame.display.set_caption("Snooker - main info window - Frame %d - %.1f%% (est. total %.1fmin)" % (i, percentage, estimated_length/60.0)) image = stream.GetFrameNo(i) image_ipl = adaptors.PIL2Ipl(image) table = get_table(image_ipl) cueballs = None best_ball = None if table: cueballs = find_cueballs(image_ipl, table) if cueballs: # See if the best cueball we found now, is the best cueball found in the previous run, # which would mean that it's standing still. Only consider the best matches. if not last_best_cueball: last_best_cueball = cueballs[0] else: distance_to_last = math.sqrt( (last_best_cueball.x-cueballs[0].x)**2 + (last_best_cueball.y-cueballs[0].y)**2 ) distance_to_last_confirmed = math.sqrt( (last_confirmed_cueball.x-cueballs[0].x)**2 + (last_confirmed_cueball.y-cueballs[0].y)**2 ) if distance_to_last < CUEBALL_CONFIRM_DISTANCE and distance_to_last_confirmed > CUEBALL_NOMOVEMENT_DISTANCE: if cueballs[0].confidence >= 0.72: # Extra check to remove most of the false positives # CONFIRMED last_confirmed_cueball = cueballs[0] cueballs[0].confirmed = True if DEBUG: print("CONFIRMED cueball %s" % cueballs[0]) else: if DEBUG: print("Dropped the ball because distance condition failed: %.2f<%d and %.2f>%d" % (distance_to_last, CUEBALL_CONFIRM_DISTANCE, distance_to_last_confirmed, CUEBALL_NOMOVEMENT_DISTANCE)) # If confirmation or sequence fail, reset and try the whole thing again last_best_cueball = False image_interesting = draw_interesting_stuff(image, table, cueballs) window.blit(image_interesting, (0,0)) pygame.display.flip() store_results(image_interesting, table, cueballs) for event in pygame.event.get(): if event.type == pygame.QUIT: out_file.close() sys.exit(0) else: pass #print event # Skip <interval> frames i += interval out_file.close()
def removeMinimum(img, x, y, w, h): """Utility function for removing the global minimum from a cvArray. This finds the global maximum of the same array and then blits a rectangle of the same color over the area designated by x,y and w,h. This way to find the next _local_ minimum, we can just remove the current global minimum and search for the global one again using cvMinMaxLoc - should be faster than looking for all local minima with python.""" minmax = cvMinMaxLoc(img) cvRectangle(img, cvPoint(x-int(w/2), y-int(h/2)), cvPoint(x+int(w/2), y+int(h/2)), cvScalar(minmax[1], 0, 0, 0), CV_FILLED)
def text(image, x, y, a_string): font = cv.cvInitFont(CV_FONT_HERSHEY_SIMPLEX, .3, .3) cv.cvPutText(image, a_string, cv.cvPoint(x, y), font, cv.cvScalar(0,0,0)) cv.cvPutText(image, a_string, cv.cvPoint(x+1, y+1), font, cv.cvScalar(255,255,255))