def end_anim(screen, win): """ This function handles the final animation of a game. - screen: pygame.display to draw to. - win: Whether or not the user won. Play a sound and display an image accordingly. """ global X global Y global background if win: img = pygame.image.load("template-minigame_files" + utils.sep + "win.png").convert_alpha() else: img = pygame.image.load("template-minigame_files" + utils.sep + "lose.png").convert_alpha() screen.fill((0, 0, 0)) screen.blit(background, (0, 0)) img_rect = img.get_rect() img_rect.center = (utils.width / 2, utils.height/2) screen.blit(img, img_rect) # Sound if win: pygame.mixer.Sound.play(utils.win_sound).set_volume(utils.volume) else: pygame.mixer.Sound.play(utils.lose_sound).set_volume(utils.volume) # Info utils.draw_points(screen) utils.draw_time(screen, utils.time_remaining) pygame.display.flip() pygame.time.wait(3000)
def do_model_pointcloud_sampling(args, config, vis=None, vis_prefix=None): # For each class, sample model points on its surface. for class_i, class_name in enumerate(config["objects"].keys()): class_rbt = RigidBodyTree() frame = RigidBodyFrame("frame", class_rbt.world(), np.zeros(3), np.zeros(3)) model_path = config["objects"][class_name]["model_path"] _, extension = os.path.splitext(model_path) if extension == ".urdf": AddModelInstanceFromUrdfFile(model_path, FloatingBaseType.kFixed, frame, class_rbt) elif extension == ".sdf": AddModelInstancesFromSdfString( open(model_path).read(), FloatingBaseType.kFixed, frame, class_rbt) else: raise ValueError("Class %s has non-sdf and non-urdf model name." % class_name) # Sample model points model_points, model_normals = sample_points_on_body( class_rbt, 1, 0.005) print "Sampled %d model points from model %s" % (model_points.shape[1], class_name) save_pointcloud(model_points, model_normals, os.path.join(args.dir, "%s.pc" % (class_name))) if vis: model_pts_offset = (model_points.T + [class_i, 0., -1.0]).T draw_points(vis, vis_prefix, class_name, model_pts_offset, model_normals, size=0.0005, normals_length=0.00)
def of_dataset(folder="testset", model=None, view=False): '''measure the error across the given dataset, it compares the measured points with the annotated ground truth, optionally you can [view] the results''' assert (model) # load face and landmark detectors utils.load_shape_predictor(model) # utils.init_face_detector(True, 150) # init average-error err = 0 num = 0 for img, lmarks, path in utils.ibug_dataset(folder): # detections face = utils.prominent_face(utils.detect_faces(img, detector="dlib")) measured = utils.detect_landmarks(img, face) # get error num += 1 err += normalized_root_mean_square(lmarks, measured) # results: if view is True: utils.draw_rect(img, face, color=Colors.yellow) utils.draw_points(img, lmarks, color=Colors.green) utils.draw_points(img, measured, color=Colors.red) utils.show_image(utils.show_properly(utils.crop_image(img, face))) print(err, num, err / num) print("average NRMS Error for {} is {}".format(folder, err / num))
def build_trainset(input_dir="data", output_dir="trainset", win_size=321): '''scan the input folder and put every image with annotations output folder''' utils.init_face_detector(True, win_size) utils.load_shape_predictor("dlib/shape_predictor_68_face_landmarks.dat") count = int(utils.count_files_inside(output_dir) / 8) window = "window" cv2.namedWindow(window) for face, box in utils.faces_inside(input_dir, 1, True): face_copy = face.copy() face_rect = region(face) # detections points = utils.detect_landmarks(face, face_rect) utils.draw_points(face, points) # show face while (1): h, w = face.shape[:2] if h > 0 and w > 0: cv2.imshow(window, show_properly(face)) else: break key = cv2.waitKey(20) & 0Xff if key == Keys.ESC: break # skip current face elif key == Keys.S: path = f"{output_dir}/face{count}" # save image cv2.imwrite(f"{path}.jpg", face_copy) # save annotation relative to the current face Annotation(f"{path}.ann", face_rect, points).save() # generate and save augumetations array = augment_data(face_copy, face_rect, points) for i, x in enumerate(array): # save image x[0] cv2.imwrite(f"{path}_{i + 1}.jpg", x[0]) # save annotations Annotation(f"{path}_{i + 1}.ann", face_rect, x[1]).save() count = count + 1 break elif key == Keys.Q: # quit program return cv2.destroyAllWindows() cv2.destroyAllWindows()
def draw_boxes_on_points(fname, data): pc = np.fromfile(data, np.float32).reshape(-1, 4) bboxes = [] read_annotation_kitti(bboxes, fname) fig = mlab.figure(figure=None, bgcolor=(0, 0, 0), fgcolor=None, engine=None, size=(1600, 1000)) draw_points(fig, pc) draw_boxes(fig, bboxes) mlab.show()
def compare_models(folder="testset", m1=None, m2=None, view=False): '''compare the [m1] shape_predictor aganist the [m2] model, optionally you can [view] the results''' assert (m1 and m2) utils.init_face_detector(True, 150) # load models utils.load_shape_predictor(m2) sp_m2 = utils.shape_predictor utils.load_shape_predictor(m1) sp_m1 = utils.shape_predictor # init error err = 0 num = 0 for face, region in utils.faces_inside(folder): h, w = face.shape[:2] if h == 0 or w == 0: continue box = utils.Region(0, 0, region.width, region.height) # detect landmarks utils.shape_predictor = sp_m1 lmarks_m1 = utils.detect_landmarks(face, box) utils.shape_predictor = sp_m2 lmarks_m2 = utils.detect_landmarks(face, box) # update error: num += 1 # err += normalized_root_mean_square(lmarks_m1, lmarks_m2) # results: if view is True: utils.draw_points(face, lmarks_m1, color=Colors.green) utils.draw_points(face, lmarks_m2, color=Colors.red) utils.show_image(utils.show_properly(face)) if num != 0: err /= num print("the NRMSE of m1 aganist m2 is {}".format(err))
def end_anim(screen, points, decrease_lives): """ This function handles the final animation of a game. - screen: pygame.display to draw to. - points: points scored """ global X global Y global background if points == 5: img = pygame.image.load("overcoock_files" + utils.sep + "win.png").convert_alpha() elif points == 2: img = pygame.image.load("overcoock_files" + utils.sep + "ok.png").convert_alpha() else: decrease_lives() img = pygame.image.load("overcoock_files" + utils.sep + "lose.png").convert_alpha() screen.fill((0, 0, 0)) screen.blit(background, (0, 0)) img_rect = img.get_rect() img_rect.center = (utils.width / 2, utils.height / 2) screen.blit(img, img_rect) # Increment points utils.points += points # Sound if points > 0: pygame.mixer.Sound.play(utils.win_sound).set_volume(utils.volume) else: pygame.mixer.Sound.play(utils.lose_sound).set_volume(utils.volume) # Info utils.draw_points(screen) utils.draw_time(screen, utils.time_remaining) pygame.display.flip() pygame.time.wait(3000)
def test(folder="testset", model="dlib/shape_predictor_68_face_landmarks.dat"): utils.init_face_detector(True, 150) utils.load_shape_predictor(model) my_sp = utils.shape_predictor dlib_sp = dlib.shape_predictor( "dlib/shape_predictor_68_face_landmarks.dat") for face, r in utils.faces_inside(folder): box = region(face) utils.shape_predictor = my_sp lmarks0 = utils.detect_landmarks(face, box) utils.shape_predictor = dlib_spq lmarks1 = utils.detect_landmarks(face, box) # draw results utils.draw_points(face, lmarks1, color=Colors.green) utils.draw_points(face, lmarks0, color=Colors.red) utils.show_image(show_properly(face))
def human_exist_or_not(cap, estimator): while cap.isOpened(): print('hi') for i in range( 5 ): # cam property: buffer size = 4, if set 5, it will read the current frame ret, img = cap.read() # ret, img = cap.read() if not ret: print('ERROR: FAILED TO CAPTURE IMAGE') return # return none == false!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! how to deal with it when it happens????????? if img is not None: # borrowed from run_webcam.py humans = estimator.inference(img, resize_to_default=True, upsample_size=4.0) # human.score ? part.score? if len(humans) == 0: print('没有检测到人体') cv2.imwrite('没有检测到人体' + str(time.time()) + '.jpg', img) return else: scores = np.array([h.score for h in humans]) res = (scores >= HUMAN_EXIST_OR_NOT_THRESHOLD) # 0.2 print(scores) if res.any(): # 持续提醒离开 speech( MP3_DIC['end'] ) # 4 seconds 暂停模块,避免持续重复发声!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 draw_points(img, humans) cv2.imwrite(str(time.time()) + '.jpg', img) time.sleep(4) continue else: print('检测到人,但是人的分数极小,可能人已经出镜了,视为假阳性') return
def test_augment(): utils.init_face_detector(True, 321) utils.load_shape_predictor("dlib/shape_predictor_68_face_landmarks.dat") for img in utils.images_inside("trainset"): points = utils.detect_landmarks(img, region(img)) angle = 30 h, w = img.shape[:2] center = (w / 2, h / 2) # 30 degree rotation rot1 = utils.rotate_image(img, angle) rot_pts1 = utils.rotate_landmarks(points, center, angle) # -30 degree rotatation rot2 = utils.rotate_image(img, -angle) rot_pts2 = utils.rotate_landmarks(points, center, -angle) # mirroring mir = utils.flip_image(img) mir_pts = utils.detect_landmarks(mir, region(mir)) utils.draw_points(img, points) utils.draw_points(rot1, rot_pts1, color=Colors.cyan) utils.draw_points(rot2, rot_pts2, color=Colors.purple) utils.draw_points(mir, mir_pts, color=Colors.green) while True: cv2.imshow("image", img) cv2.imshow("mirrored", mir) cv2.imshow("rotated30", rot1) cv2.imshow("rotated-30", rot2) key = cv2.waitKey(20) & 0Xff if key == Keys.ESC: break elif key == Keys.Q: return cv2.destroyAllWindows()
def make_logo_frame( frame: np.ndarray, mask: np.ndarray, texture: np.ndarray, texture_mask: np.ndarray, h**o: np.ndarray, draw_points: bool = True, texture_points: np.ndarray = None, point_color: Tuple[int, int, int] = (153, 255, 153) ) -> np.ndarray: img_size = frame.shape[1], frame.shape[0] texture, texture_mask = warp_img_to_texture(texture, texture_mask, h**o, texture_size=img_size) logo_mask = cv2.bitwise_and(mask, texture_mask) logo_mask_inv = cv2.bitwise_not(logo_mask) img1_bg = cv2.bitwise_and(frame, frame, mask=logo_mask_inv) img2_fg = cv2.bitwise_and(texture, texture, mask=logo_mask) new_frame = cv2.add(img1_bg, img2_fg) if draw_points: new_points = cv2.perspectiveTransform(src=np.array( [texture_points.reshape(-1, 2)]), m=h**o)[0] new_frame = utils.draw_points(new_frame, new_points, color=point_color, draw_ids=True, point_ids=list(range(0, 8))) return new_frame
def dinorun_game(screen, get_data, decrease_lives): """ This function handles the dinorun minigame. - screen: pygame.display to draw to. - get_data: get_data function to retrieve data from the microbit. """ global X global Y global background # Initialise points variable points_counter = utils.points # Init dinosaur sprite dinosaur_sprite = dinorun_files.dino.Dino() dinosaur_sprite_g = pygame.sprite.Group() dinosaur_sprite_g.add(dinosaur_sprite) # Init wizard sprite wizard_sprite = dinorun_files.wizard.Wizard() wizard_sprite_g = pygame.sprite.Group() wizard_sprite_g.add(wizard_sprite) # Load backgound image background = pygame.image.load("dinorun_files" + utils.sep + "background.png").convert_alpha() # Game pygame.mixer.music.load("dinorun_files" + utils.sep + "music.ogg") pygame.mixer.music.play(1) # Do not loop the song, play it once. -1 to play in a loop if you ever need it. seconds_counter = time.time() utils.text_colour = (0, 0, 224) # Set the text colour for the minigame while True: if time.time() - seconds_counter > 1: utils.time_remaining -= 1 seconds_counter = time.time() if utils.time_remaining > 0: utils.run_in_thread(get_data) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() screen.fill((0, 0, 0)) jump = (utils.data[0] == 1) dinosaur_sprite.animate(jump) wizard_sprite.animate(dinosaur_sprite.rect) screen.blit(background, (0, 0)) dinosaur_sprite_g.draw(screen) wizard_sprite_g.draw(screen) dinosaur_sprite_g.update() wizard_sprite_g.update() # Info utils.draw_text(screen, "U to jump", utils.width / 2, 322) utils.draw_points(screen) utils.draw_time(screen, utils.time_remaining) utils.run_in_thread(utils.draw_volume(screen)) pygame.display.flip() utils.clock.tick(60) else: pygame.mixer.music.stop() if utils.points - points_counter < 6: # If true, the user lost decrease_lives() end_anim(screen, False) else: end_anim(screen, True) utils.minigame_end(screen, get_data) break return
def build_trainset_auto(src="dataset", dst="trainset", debug=False): '''build a trainset automatically from an ibug-like dataset, the images are taken from [src] folder and saved to [dst] folder''' utils.init_face_detector(True, 150) qualiy = [int(cv2.IMWRITE_JPEG_QUALITY), 50] # file count for naming count = int(utils.count_files_inside(dst) / 8) for img, lmarks, path in utils.ibug_dataset(src): h, w = img.shape[:2] # crop a bigger region around landmarks region = utils.points_region(lmarks) scaled = region.scale(1.8, 1.8).ensure(w, h) img = utils.crop_image(img, scaled) # detect faces face = utils.prominent_face(utils.detect_faces(img)) # if cnn fails try with dlib if face is None: faces = utils.detect_faces(img, detector="dlib") # ..if dlib fails take the region around landmarks if face is None: face = region.copy() else: face = utils.prominent_face(faces) # edit landmarks according to scaled region lmarks = adjust_landmarks(scaled, lmarks) # augumentations i = 0 for image, landmarks, box in augment_data(img, face, lmarks): i = i + 1 if debug: utils.draw_rect(image, box, color=Colors.yellow) utils.draw_points(image, landmarks, color=Colors.purple) name = f"image{i}" utils.show_image(show_properly(image), window=name) else: # save annotation and image ipath = os.path.join(dst, f"face{count}_{i}.jpg") apath = os.path.join(dst, f"face{count}_{i}.ann") cv2.imwrite(ipath, image, qualiy) Annotation(apath, box.as_list()[:4], landmarks).save() if debug: utils.draw_rect(img, face, color=Colors.red) utils.draw_points(img, lmarks, color=Colors.green) utils.show_image(show_properly(img)) else: # save image and annotation ipath = os.path.join(dst, f"face{count}.jpg") apath = os.path.join(dst, f"face{count}.ann") cv2.imwrite(ipath, img, qualiy) Annotation(apath, face.as_list()[:4], lmarks).save() count = count + 1 # info print("{} processed: {}\r".format(count, ipath))
def whichpath_game(screen, get_data, decrease_lives): """ This function handles the 'template-minigame' minigame. - screen: pygame.display to draw to. - get_data: get_data function to retrieve data from the microbit. """ global X global Y global background # Initialise points variable points_counter = utils.points # Load main sprite: # Use this method only if the sprite is a single image. # If you want to animate it, jump to line #68 # to see how to import an animated sprite. character_sprite = pygame.image.load("whichpath_files" + utils.sep + "character_F.png").convert_alpha() # Main sprite's coordinates X = (utils.width / 2) - (32 / 2) # 32 is the sprite's width Y = utils.height - 50 - 32 # 32 is the sprite's height, just an example # Init animated sprite character = whichpath_files.character.character() character_sprites = pygame.sprite.Group() character_sprites.add(character) # Load backgound image background = pygame.image.load("whichpath_files" + utils.sep + "background.png").convert_alpha() # Game pygame.mixer.music.load("whichpath_files" + utils.sep + "music.ogg") pygame.mixer.music.play( 1 ) # Do not loop the song, play it once. -1 to play in a loop if you ever need it. seconds_counter = time.time() utils.text_colour = (255, 255, 255) # Set the text colour for the minigame while True: # Game logic if utils.points - points_counter == 2: # Winning condition pygame.mixer.music.stop() end_anim(screen, True) utils.time_remaining = 0 # Make sure the game stops if time.time() - seconds_counter > 1: # Timer utils.time_remaining -= 1 seconds_counter = time.time() if utils.time_remaining > 0: # Enough time remaining condition utils.run_in_thread(get_data) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() screen.fill((0, 0, 0)) # Microbit input here. Manipulate the data # as per minigame's needs. The data comes in # an array stored in the utils.data variable. # Example of data manipulation (from dinorun minigame): if utils.data[0] == 2 and X > 0: # Left X -= 5 elif utils.data[0] == 4 and X < utils.width: # Right X += 5 character_rect = character_sprite.get_rect(center=(X, Y)) finnished = 0 if (X < 400 and finnished == 0): utils.points += 1 pygame.mixer.music.stop() end_anim(screen, True) utils.time_remaining = 0 # Make sure the game stops finnished += 1 elif (X > 1200 and finnished == 0): pygame.mixer.music.stop() utils.time_remaining = 0 # Make sure the game stops finnished += 1 character.animate(character_rect) screen.blit(background, (0, 0)) #character_sprites.draw(screen) screen.blit(character_sprite, character_rect) #character_sprites.update() # Info utils.draw_text(screen, "L or R", utils.width / 2, 322) utils.draw_points(screen) utils.draw_time(screen, utils.time_remaining) utils.run_in_thread(utils.draw_volume(screen)) pygame.display.flip() utils.clock.tick(60) # Pick the clock that best suits your game else: pygame.mixer.music.stop() if utils.points - points_counter < 1: # If true, the user lost. Feel free to change the points needed to win decrease_lives() end_anim(screen, False) utils.minigame_end(screen, get_data) break return
lblink, rblink = bd.predict_states(imgContainer['gray'], fd.detectedEyeAreas[0], fd.detectedEyeAreas[1]) blinkEvent = ma.analyze_blink_event((lblink, rblink)) if mouseCaptureEnabled: mouse.move_mouse_pointer(relMoveFiltered[0], relMoveFiltered[1]) if blinkEvent != BlinkEvent.NoBlink: mouse.blink_event_to_action(blinkEvent) else: cv2.putText(vis, 'press \'z\' to toggle mouse capture', (20, 220), cv2.FONT_HERSHEY_COMPLEX, 1, 255) # visualise u.draw_rects(vis, fd.detectedEyeAreas) u.draw_points(vis, fd.trackedPoint) u.draw_blink_event(vis, blinkEvent) else: cv2.putText(vis, 'detecting face', (210, 460), cv2.FONT_HERSHEY_COMPLEX, 1, 255) cv2.imshow('Preview', vis) endTime = time.time() # print "Processing delay ", int(round((endTime - startTime) * 1000)), " ms" # limit processing speed up to 30 FPS if endTime - startTime < 0.032: time.sleep(0.032 - (endTime - startTime)) key = cv2.waitKey(2)
def templateminigame_game(screen, get_data, decrease_lives): """ This function handles the 'template-minigame' minigame. - screen: pygame.display to draw to. - get_data: get_data function to retrieve data from the microbit. """ global X global Y global background # Initialise points variable points_counter = utils.points # Load main sprite: # Use this method only if the sprite is a single image. # If you want to animate it, jump to line #68 # to see how to import an animated sprite. main_sprite = pygame.image.load("template-minigame_files" + utils.sep + "main.png").convert_alpha() # Main sprite's coordinates X = 600 Y = utils.height - 20 - 320 # 320 is the sprite's height, just an example # Init animated sprite animated_sprite = template-minigame_files.sprite1.Sprite1() animated_sprite_g = pygame.sprite.Group() animated_sprite_g.add(animated_sprite) # Load backgound image background = pygame.image.load("template-minigame_files" + utils.sep + "background.png").convert_alpha() # Game pygame.mixer.music.load("template-minigame_files" + utils.sep + "music.ogg") pygame.mixer.music.play(1) # Do not loop the song, play it once. -1 to play in a loop if you ever need it. seconds_counter = time.time() utils.text_colour = (255, 255, 255) # Set the text colour for the minigame while True: # Game logic if time.time() - seconds_counter > 1: # Timer utils.time_remaining -= 1 seconds_counter = time.time() if utils.time_remaining > 0: # Enough time remaining condition utils.run_in_thread(get_data) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() screen.fill((0, 0, 0)) # Microbit input here. Manipulate the data # as per minigame's needs. The data comes in # an array stored in the utils.data variable. # Example of data manipulation (from dinorun minigame): jump = (utils.data[0] == 1) animated_sprite.animate() screen.blit(background, (0, 0)) animated_sprite_g.draw(screen) animated_sprite_g.update() # Info utils.draw_text(screen, "Insert info here", utils.width / 2, 322) utils.draw_points(screen) utils.draw_time(screen, utils.time_remaining) utils.run_in_thread(utils.draw_volume(screen)) pygame.display.flip() utils.clock.tick(60) # Pick the clock that best suits your game else: pygame.mixer.music.stop() if utils.points - points_counter < 6: # If true, the user lost. Feel free to change the points needed to win decrease_lives() end_anim(screen, False) else: end_anim(screen, True) utils.minigame_end(screen, get_data) break return
def match_game(screen, get_data, decrease_lives): """ This function handles the match minigame. - screen: pygame.display to draw to. - get_data: get_data function to retrieve data from the microbit. """ global X global Y global background # Initialise here the points variables points = 0 # Load drinks sprite: red_sprite = pygame.image.load("match_files" + utils.sep + "red.png").convert_alpha() green_sprite = pygame.image.load("match_files" + utils.sep + "green.png").convert_alpha() blue_sprite = pygame.image.load("match_files" + utils.sep + "blue.png").convert_alpha() # Drink sprites' coordinates X = utils.width Y = utils.height / 2 # Load backgound image background = pygame.image.load("match_files" + utils.sep + "background.png").convert_alpha() # Game pygame.mixer.music.load("match_files" + utils.sep + "music.ogg") seconds_counter = time.time() generated = False potions_list = [red_sprite, green_sprite, blue_sprite] shuffle(potions_list) # Shuffle list buttons_list_tmp = [1, 2, 3, 4] shuffle(buttons_list_tmp) # Shuffle list buttons_list = [] for i in range(0, 3): buttons_list.append( buttons_list_tmp[i]) # make buttons and potions list same length index = 0 button_press = 0 colour = (255, 250, 0) utils.text_colour = colour utils.text_colour = (255, 255, 255) # Set the text colour for the minigame directions(screen, potions_list, buttons_list, get_data) utils.text_colour = colour pygame.mixer.music.play(-1) # Game can last more than 27 seconds while True: # Game logic if points == 12: # winning condition pygame.mixer.music.stop() end_anim(screen, True) utils.time_remaining = 0 # Make sure the game stops if time.time() - seconds_counter > 1: utils.time_remaining -= 1 seconds_counter = time.time() if utils.time_remaining > 0: utils.run_in_thread(get_data) utils.check_data_integrity(screen) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() screen.fill((0, 0, 0)) if index == 3: index = 0 generated = False if generated == False: potions_list, buttons_list = shuffle_lists( potions_list, buttons_list) generated = True # Make sure button presses are not duplicated if utils.data[0] != button_press: button_press = utils.data[0] else: button_press = 0 if button_press == buttons_list[index]: blit_all(screen, potions_list, index) index += 1 points += 1 utils.points += 1 counter = 0 utils.text_colour = (9, 140, 0) utils.draw_text(screen, "Right!", X / 2, Y / 2) pygame.display.flip() pygame.time.wait(1200) utils.text_colour = colour utils.time_remaining += 3 utils.data[0] = 0 elif button_press != 0: blit_all(screen, potions_list, index) utils.text_colour = (0, 4, 198) utils.draw_text(screen, "Wrong!", X / 2, Y / 2) pygame.display.flip() pygame.time.wait(1200) utils.text_colour = colour utils.time_remaining -= 7 utils.data[0] = 0 blit_all(screen, potions_list, index) # Info #utils.draw_text(screen, "Directions", utils.width / 2, 322) utils.draw_points(screen) utils.draw_time(screen, utils.time_remaining) utils.run_in_thread(utils.draw_volume(screen)) pygame.display.flip() utils.clock.tick(60) else: pygame.mixer.music.stop() if points < 12: # If true, the user lost decrease_lives() end_anim(screen, False) utils.minigame_end(screen, get_data) break return
# draw the 3d bbox to check # 将原始图片读取出来 print(test_img_path) print(type(test_img_path)) test_img_path: str = test_img_path[0] test_image = Image.open(test_img_path) test_image_points = test_image.copy() test_image.save( '/home/ryan/Codes/VotingNet6DPose/log_info/results/test_original_image.jpg' ) # test_image_with_boxes = draw_3d_bbox(test_image, pred_keypoints[1:], 'blue') test_image_label_path = test_img_path.replace('JPEGImages', 'labels') test_image_label_path = test_image_label_path.replace('jpg', 'txt') gt_keypoints = LinemodDatasetProvider.provide_keypoints_coordinates( test_image_label_path)[1].numpy() print('GT keypoints:\n', gt_keypoints) # test_image_with_boxes = draw_3d_bbox(test_image_with_boxes, gt_keypoints[1:], 'green') # 保存结果 # test_image_with_boxes.save('/home/ryan/Codes/VotingNet6DPose/log_info/results/result_image.jpg') point_image = draw_points(test_image_points, pred_keypoints, color='blue') draw_points(point_image, gt_keypoints, color='green').save( '/home/ryan/Codes/VotingNet6DPose/log_info/results/result_points_img.jpg' ) if i == 0: break
def human_pose(cap, estimator): """ :param img: :return: whether human pose is okay RShoulder = 2 RElbow = 3 RWrist = 4 LShoulder = 5 LElbow = 6 LWrist = 7 """ # cv2.namedWindow('window', cv2.WINDOW_NORMAL) cnt = 0 while cap.isOpened(): cnt += 1 if cnt % 60 == 0: speech(MP3_DIC['poseMaking']) # 6 seconds cnt = 0 time.sleep( 6) # 给客户6秒钟时间调整姿势,再进行检测, 是否语音要缩短????????????????????????? print("*" * 30) # ret, img = cap.read() # clear cache for i in range( 5 ): # cam property: buffer size = 4, if set 5, it will read the current frame ret, img = cap.read() if not ret: print('ERROR: FAILED TO CAPTURE IMAGE') return # return none == false!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! how to deal with it when it happens????????? if img is not None: # borrowed from run_webcam.py humans = estimator.inference(img, resize_to_default=True, upsample_size=4.0) print(humans) print(*[h.score for h in humans]) draw_points(img, humans) cv2.imshow('window', img) # if cv2.waitKey(1) & 0xFF == ord('q'): # break # human.score ? part.score? if len(humans) == 0: print('没有检测到人体') continue elif len(humans) == 1: target = humans[0] dic = target.body_parts res = [dic.get(i) for i in range(2, 8)] # 虽然检测到人,但是核心部位缺失 if None in res: print('虽然检测到人,但是核心部位缺失') continue # RShoulder, RElbow, RWrist, LShoulder, LElbow, LWrist = res part_score = np.array([part.score for part in res ]) >= PART_SCORE_THRESHOLD if part_score.all(): if pose_correct_or_not_overlook(res): print('姿势正确') cv2.imwrite('./keypoints/' + str(time.time()) + '.jpg', img) return True else: # 提示姿势矫正 print('提示姿势矫正') continue else: # 有一些关键点置信度过低 print('有一些关键点置信度过低') continue else: print('检测到多个人体骨骼') ## 策略一: continue,作废. 策略二:选取分数高的那个 continue
def calc_scene_homography_and_texture( init_homo: np.ndarray, video_scene: VideoScene, texture_points: np.ndarray, frame_dir: Union[str, Path], mask_dir: Union[str, Path], texture_dir: Union[str, Path], texture_size: Tuple[int, int] = (1280, 1280), texture_alpha: float = 0.1, result_name: str = ('ufc234_gastelum_bisping_1080p_nosound_cut' '__homography'), result_dir: Union[str, Path] = '../data/video/info', draw_points: bool = False, point_color: Tuple[int, int, int] = (153, 255, 153), point_radius: int = 10, point_font_scale: float = 1.5, point_font_thickness: int = 2 ) -> Tuple[Dict[int, Dict[str, np.ndarray]], np.ndarray, np.ndarray]: frame_dir = Path(frame_dir) mask_dir = Path(mask_dir) # result directories result_dir = Path(result_dir) texture_dir = Path(texture_dir) result_dir.mkdir(parents=True, exist_ok=True) texture_dir.mkdir(parents=True, exist_ok=True) result: Dict[int, Dict[str, np.ndarray]] = {} h**o = HomographyHelper() first_frame_n = video_scene.get_first_frame() num_frames = video_scene.get_num_frames() # save init_homo to result prev_frame_n = first_frame_n result[prev_frame_n] = {'texture': init_homo} # save previous frame and mask prev_frame, prev_mask = utils.load_frame_and_mask(frame_n=prev_frame_n, frame_dir=frame_dir, mask_dir=mask_dir) # init texture main_texture, main_texture_mask = warp_img_to_texture( prev_frame, prev_mask, init_homo, texture_size=texture_size) # also save texture with image points if draw_points: img_points = utils.draw_points(main_texture, texture_points, color=point_color, draw_ids=True, point_ids=list(range(0, 8)), radius=point_radius, font_scale=point_font_scale, font_thickness=point_font_thickness) else: img_points = None _save_frame_and_mask(frame=main_texture, mask=main_texture_mask, frame_n=prev_frame_n, output_dir=texture_dir, points=img_points) # we don't use frame_0 # because all information is in init_homo first_frame_n += 1 for frame_n in tqdm(range(first_frame_n, num_frames)): frame, mask = utils.load_frame_and_mask(frame_n=frame_n, frame_dir=frame_dir, mask_dir=mask_dir) # считаем homography между предыдущим кадром # в сцене и текущим кадром homo_res = h**o.calc_homography(images=(prev_frame, frame), masks=(prev_mask, mask)) if homo_res is None: result[frame_n]['texture'] = None print(f'No homography for frame {frame_n}') continue else: matches, H_frames, status = homo_res # считаем временную homography # для преобразования из текущего кадра в текстуру homo_texture = result[prev_frame_n]['texture'] H_tmp = homo_texture.dot(np.linalg.inv(H_frames)) # делаем warp текущего кадра в текстуру tmp_texture, tmp_texture_mask = warp_img_to_texture( frame, mask, H_tmp, texture_size=texture_size) # считаем homography между текстурой # текущего кадра и текстурой предыдущего # для корректировки homography homo_res = h**o.calc_homography(images=(main_texture, tmp_texture), masks=(main_texture_mask, tmp_texture_mask)) if homo_res is None: result[frame_n]['texture'] = None print(f'No homography for frame {frame_n}') continue else: matches, H_tex, status = homo_res # H_tmp = texture -> frame # H_tex = texture -> main_texture # np.linalg.inv(H_tex) = main_texture -> texture # main_texture -> frame # корректируем homography H_new = np.linalg.inv(H_tex).dot(H_tmp) result[frame_n] = {'texture': H_new} # get textures for current frame texture, texture_mask = warp_img_to_texture(frame, mask, H_new, texture_size=texture_size) # main texture unique part main_texture_unique = cv2.bitwise_and( main_texture, main_texture, mask=cv2.bitwise_not(texture_mask)) # new frame texture unique part new_texture_unique = cv2.bitwise_and( texture, texture, mask=cv2.bitwise_not(main_texture_mask)) # only unique parts of main and new textures unique_texture = cv2.add(main_texture_unique, new_texture_unique) # updating running average part # of main texture intersection_mask = cv2.bitwise_and(main_texture_mask, texture_mask) intersection_texture = cv2.addWeighted( cv2.bitwise_and(main_texture, main_texture, mask=intersection_mask), (1 - texture_alpha), cv2.bitwise_and(texture, texture, mask=intersection_mask), texture_alpha, 0) # updated main texture main_texture = cv2.add(intersection_texture, unique_texture) # mask union main_texture_mask = cv2.bitwise_or(main_texture_mask, texture_mask) # also save texture with image points if draw_points: img_points = utils.draw_points(main_texture, texture_points, color=point_color, draw_ids=True, point_ids=list(range(0, 8)), radius=point_radius, font_scale=point_font_scale, font_thickness=point_font_thickness) else: img_points = None _save_frame_and_mask(frame=main_texture, mask=main_texture_mask, frame_n=frame_n, output_dir=texture_dir, points=img_points) # сохраняем данные с текущего кадра prev_frame_n = frame_n prev_frame, prev_mask = frame, mask # save homographies # _save_scene_homo(result, name=result_name, output_dir=result_dir) return result, main_texture, main_texture_mask
def wheelie_game(screen, get_data, decrease_lives): """ This function handles the 'wheelie' minigame. - screen: pygame screen. - get_data: get_data function to retrieve data from the microbit. """ global angle global angle_opponent global background # Initialise points variable points_counter = utils.points # Init bike sprite X = 350 Y = (utils.height - 15) - (372 / 2) # 372 is the sprite's height, 20 is the floor's height bike = wheelie_files.bike.Bike(X, Y, False) bike_sprites = pygame.sprite.Group() bike_sprites.add(bike) angle = 0 # Init opponent bike sprite X = 950 opponent = wheelie_files.bike.Bike(X, Y, True) opponent_sprites = pygame.sprite.Group() opponent_sprites.add(opponent) # Init backgound images background = pygame.image.load("wheelie_files" + utils.sep + "background.png").convert_alpha() # Game pygame.mixer.music.load("wheelie_files" + utils.sep + "music.ogg") pygame.mixer.music.play(1) # Do not loop the song, play it once. -1 to play in a loop if you ever need it. seconds_counter = time.time() mathcing_time_remaining = 3 utils.text_colour = (255, 0, 0) while True: if time.time() - seconds_counter > 1: utils.time_remaining -= 1 mathcing_time_remaining -= 1 # Check if the user has matched the opponent if mathcing_time_remaining == 0: mathcing_time_remaining = 3 if abs(angle - angle_opponent) <= 15: utils.points += 1 angle_opponent = randint(0, 70) seconds_counter = time.time() if utils.time_remaining > 0: utils.run_in_thread(get_data) utils.check_data_integrity(screen) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() screen.fill((0, 0, 0)) # Backgound scroll_background(background, screen) # Check what button has been pressed if utils.data[0] == 3 and angle > 0: # Down angle -= 0.5 elif utils.data[0] == 1 and angle < 70: # Up angle += 0.5 bike_sprites.draw(screen) opponent_sprites.draw(screen) bike.wheel_angle(angle) opponent.wheel_angle(angle_opponent) bike_sprites.update() opponent_sprites.update() # Info utils.draw_text(screen, "U/D to wheelie", utils.width / 2, 322) utils.draw_points(screen) utils.draw_time(screen, utils.time_remaining) utils.draw_number_counter(screen, mathcing_time_remaining) utils.run_in_thread(utils.draw_volume(screen)) pygame.display.flip() utils.clock.tick(60) else: pygame.mixer.music.stop() if utils.points - points_counter < 3: # If true, the user lost. decrease_lives() end_anim(screen, False) else: end_anim(screen, True) utils.minigame_end(screen, get_data) while True: get_data() for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if type(utils.data[0]) == float and utils.data[0] != 0: break break return
gt_tf[:3, 3] = gt_pose[:3] scene_points, scene_points_normals = \ load_pointcloud(os.path.join( scene_dir, example_foldername, instance_cloud_filename)) print "\t... loaded %d points for instance %d" % ( scene_points.shape[1], instance_j) if vis: print draw_points( vis, "model", "model", scene_points, colors=plt.cm.viridis( (scene_points[2, :] - np.min(scene_points[2, :])) / (np.max(scene_points[2, :]) - np.min(scene_points[2, :]))).T) # Sample params method_params = {} for param_name in method_params_ranges.keys(): method_params[param_name] = random.choice( method_params_ranges[param_name]) do_gt_init = random.choice(do_gt_init_options) if do_gt_init is True: method_params["tf_init"] = gt_tf.copy() # Finally, run the fitter!
0.03)) def mark_opticalflow(previous_points, previous_gray, current_gray): p1, st, err = cv2.calcOpticalFlowPyrLK(previous_gray, current_gray, previous_points, None, **lk_params) good_new = p1[st == 1] good_old = p0[st == 1] return good_new if __name__ == '__main__': cap = cv2.VideoCapture('videos/example.avi') ret, frame = cap.read() previous_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) p0 = np.array( [[[89.2954, 387.04]], [[117.159, 392.263]], [[75.3686, 317.383]], [[89.302, 380.012]], [[115.393, 381.788]]], dtype=np.float32) while (True): ret, frame = cap.read() if ret is False: break current_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) new_p = mark_opticalflow(p0, previous_gray, current_gray) p0 = new_p.reshape(-1, 1, 2) previous_gray = current_gray.copy() cv2.imshow('frame', draw_points(frame, new_p)) cv2.waitKey(30)
def main(): # set random seed random.seed(1) config = get_args() # generate sample data delta = 0.05 x = np.arange(0, 1, delta) y = np.arange(0, 2, delta) X, Y = np.meshgrid(x, y) data = np.concatenate((X.reshape(-1, 1), Y.reshape(-1, 1)), axis=1) # [mu, sigma, l] GP_prior = [0, np.exp(1), np.exp(-1.5)] # different algos algo = {} algo[1] = LSE(data, GP_prior, 1, False, config.cost, acc=0) algo[2] = LSE_imp(data, GP_prior, 1 / 3, True, config.cost, acc=0) algo[3] = LSE_imp_mod(data, GP_prior, 1 / 3, True, config.cost, acc=0) algo[4] = TRUVAR(data, GP_prior, 1, False, config.cost, delta=0, eta=1, r=0.1) algo[5] = TRUVAR_imp(data, GP_prior, 1 / 3, False, config.cost, delta=0, eta=1, r=0.1) algo[6] = RMILE(data, GP_prior, 1, False, config.cost, eta=0.01) algo[7] = LSE(data, GP_prior, 1, False, True, acc=0) algo[7].name = 'LSE_cost' if config.test_type == 'single': # draw points and paths start_point = random.randint(0, data.shape[0]) f1, cost, time, points = algo[config.algo[0]].run(start_point) cost = 'cost_' if config.cost else '' draw_points(points, algo[config.algo[0]].name, cost) draw_paths(points, algo[config.algo[0]].name, cost) elif config.test_type == 'cost': # draw cost and F1 plots f1s = [] costs = [] labels = [] for j in config.algo: labels.append(algo[j].name) start_point = random.randint(0, data.shape[0]) for index, j in enumerate(config.algo): print('Algo: ', algo[j].name) f1, cost, time, _ = algo[j].run(start_point) f1s.append(f1) costs.append(cost) draw_costs(costs, f1s, labels) else: # draw step and F1 plots f1s = [] labels = [] times = [] for j in config.algo: f1s.append([]) times.append([]) labels.append(algo[j].name) # iteration steps, here we choose 10 for i in range(10): print('Epoch: ', i) start_point = random.randint(0, data.shape[0]) for index, j in enumerate(config.algo): print('Algo: ', algo[j].name) f1, cost, time, _ = algo[j].run(start_point) f1s[index].append(f1) times[index].append(time) for index, j in enumerate(config.algo): avg_time = avg_list(times[index]) print(algo[j].name, 'avg_time: ', avg_time) f1_plots(f1s, labels)
order='F')[:, good_points_mask] # Rescale from int8 to float values normals = (normals.astype(np.float64) / 127.) - 1. # And transform to camera frame and then to world frame normals = tf[:3, :3].dot(depth_camera_pose[:3, :3].dot(normals)) if vis: z_heights_normalized = (points[2, :]-np.min(points[2, :])) \ / (np.max(points[2, :])-np.min(points[2, :])) label_separated_heights = z_heights_normalized + labels colors = cm.jet(label_separated_heights / np.max(label_separated_heights)).T[0:3, :] draw_points(vis, vis_prefix, "%d" % i, points, normals=normals, colors=colors, size=0.0005, normals_length=0.00) all_points.append(points) all_points_normals.append(normals) all_points_labels.append(labels) # Calculate distance to each object instance for instance_j, instance_config in enumerate(config["instances"]): this_kinsol = single_object_rbts[instance_j].doKinematics( np.zeros(6)) phi, _, _, _, _ = single_object_rbts[instance_j]\ .collisionDetectFromPoints(this_kinsol, points, use_margins=False)
def coin_game(screen, get_data, decrease_lives): """ This function handles the 'coin' minigame. - screen: pygame.display to draw to. - get_data: get_data function to retrieve data from the microbit. """ global X global Y global background # Initialise here the points variables points_counter = utils.points other_useful_var = 0 # Load bucket sprite bucket_sprite = pygame.image.load("coin_files" + utils.sep + "bucket.png").convert_alpha() # Main sprite's coordinates X = utils.width / 2 Y = utils.height - (320 / 2) - 20 # 320 is the sprite's height # Init coin sprite coin_sprite = coin_files.coin.Coin() coin_sprite_g = pygame.sprite.Group() coin_sprite_g.add(coin_sprite) # Load backgound image background = pygame.image.load("coin_files" + utils.sep + "background.png").convert_alpha() # Game pygame.mixer.music.load("coin_files" + utils.sep + "music.ogg") pygame.mixer.music.play(1) # Do not loop the song, play it once. -1 to play in a loop if you ever need it. seconds_counter = time.time() utils.text_colour = (200, 89, 78) # Set the text colour for the minigame while True: # Game logic if utils.points - points_counter == 5: # winning condition pygame.mixer.music.stop() end_anim(screen, True) utils.time_remaining = 0 # Make sure the game stops if time.time() - seconds_counter > 1: utils.time_remaining -= 1 seconds_counter = time.time() if utils.time_remaining > 0: utils.run_in_thread(get_data) utils.check_data_integrity(screen) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() screen.fill((0, 0, 0)) # Check what button has been pressed if utils.data[0] == 2 and X > 0: # Left X -= 5 elif utils.data[0] == 4 and X < utils.width: # Right X += 5 bucket_rect = bucket_sprite.get_rect(center=(X, Y)) # Coin animation coin_sprite.animate(bucket_rect) screen.blit(background, (0, 0)) coin_sprite_g.draw(screen) screen.blit(bucket_sprite, bucket_rect) coin_sprite_g.update() # Info utils.draw_text(screen, "R and L buttons to move", utils.width / 2, 222) utils.draw_points(screen) utils.draw_time(screen, utils.time_remaining) utils.run_in_thread(utils.draw_volume(screen)) pygame.display.flip() utils.clock.tick(60) else: pygame.mixer.music.stop() if utils.points - points_counter < 5: # If true, the user lost end_anim(screen, False) decrease_lives() utils.minigame_end(screen, get_data) break return
def human_pose(cap, estimator): """ :param img: :return: whether human pose is okay RShoulder = 2 RElbow = 3 RWrist = 4 LShoulder = 5 LElbow = 6 LWrist = 7 """ cv2.namedWindow('window', cv2.WINDOW_NORMAL) while cap.isOpened(): print("*" * 30) ret, img = cap.read() cv2.imshow('window', img) if cv2.waitKey(1) & 0xFF == ord('q'): break # borrowed from run_webcam.py humans = estimator.inference(img, resize_to_default=True, upsample_size=4.0) print(humans) draw_points(img, humans) cv2.imshow('window', img) if cv2.waitKey(1) & 0xFF == ord('q'): break # human.score ? part.score? if len(humans) == 0: print('没有检测到人体') continue elif len(humans) == 1: target = humans[0] dic = target.body_parts res = [dic.get(i) for i in range(2, 8)] # 虽然检测到人,但是核心部位缺失 if None in res: print('虽然检测到人,但是核心部位缺失') continue # RShoulder, RElbow, RWrist, LShoulder, LElbow, LWrist = res part_score = np.array([part.score for part in res]) >= PART_SCORE_THRESHOLD if part_score.all(): if pose_correct_or_not_overlook(res): print('姿势正确') cv2.imwrite('./ok' + str(time.time()) + '.jpg', img) return True else: # 提示姿势矫正 print('提示姿势矫正') continue else: # 有一些关键点置信度过低 print('有一些关键点置信度过低') continue else: print('检测到多个人体骨骼') ## 策略一: continue,作废. 策略二:选取分数高的那个 continue
def overcoock_game(screen, get_data, decrease_lives): """ This function handles the overcoock minigame. - screen: pygame.display to draw to. - get_data: get_data function to retrieve data from the microbit. """ global X global Y global background # Initialise here the points variables points = 0 stage = 0 presses = 0 # Init meat sprite meat_sprite = overcoock_files.meat.Meat() meat_sprite_g = pygame.sprite.Group() meat_sprite_g.add(meat_sprite) # Init fire sprite fire_sprite = overcoock_files.fire.Fire() fire_sprite_g = pygame.sprite.Group() fire_sprite_g.add(fire_sprite) # Load backgound image background = pygame.image.load("overcoock_files" + utils.sep + "background.png").convert_alpha() # Game pygame.mixer.music.load("overcoock_files" + utils.sep + "music.ogg") pygame.mixer.music.play( 1 ) # Do not loop the song, play it once. -1 to play in a loop if you ever need it. seconds_counter = time.time() utils.text_colour = (98, 28, 68) # Set the text colour for the minigame utils.data[ 0] = 0 # Resest the control number as it might get mashed from the mid minigames screen. while True: # Game logic if time.time() - seconds_counter > 1: utils.time_remaining -= 1 seconds_counter = time.time() if utils.time_remaining > 0: utils.run_in_thread(get_data) utils.check_data_integrity(screen) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() screen.fill((0, 0, 0)) # Register 125 (5 / (1 / 25)) button inputs (Down) to increase cooking state. # Register 1 button input (Up) to finish cooking. up = (utils.data[0] == 1) down = (utils.data[0] == 3) if down == True: presses += 1 / 25 if int(presses) == 5: presses = 0 if stage < 6: stage += 1 meat_sprite.animate(stage) elif up == True: if stage < 3: points = 0 elif stage < 5: points = 2 elif stage < 6: points = 5 else: points = 0 utils.time_remaining = 0 # Animate the fire sprite fire_sprite.animate() screen.blit(background, (0, 0)) meat_sprite_g.draw(screen) fire_sprite_g.draw(screen) meat_sprite_g.update() fire_sprite_g.update() # Info utils.draw_text(screen, "U to finish, D to cook", utils.width / 2, 322) utils.draw_points(screen) utils.draw_time(screen, utils.time_remaining) utils.run_in_thread(utils.draw_volume(screen)) pygame.display.flip() utils.clock.tick(60) else: pygame.mixer.music.stop() end_anim(screen, points, decrease_lives) utils.minigame_end(screen, get_data) break return
def engine_game(screen, get_data, decrease_lives): """ This function handles the 'wheelie' minigame. - screen: pygame.display to draw to. - get_data: get_data function to retrieve data from the microbit. """ global angle global angle_opponent global X global Y global car global background blow_points = 0 old_blow_points = 0 stage = 0 # Load car sprite car = pygame.image.load("engine_files" + utils.sep + "car.png").convert_alpha() # Car sprite's coordinates X = 600 Y = utils.height - 20 - 320 # 320 is the sprite's height # Init engine temperature sprite temp_indicator = engine_files.engine_temp.EngineTemp() indicator_sprites = pygame.sprite.Group() indicator_sprites.add(temp_indicator) # Init smoke sprite smoke = engine_files.smoke.Smoke() smoke_sprites = pygame.sprite.Group() smoke_sprites.add(smoke) # Load backgound image background = pygame.image.load("engine_files" + utils.sep + "background.png").convert_alpha() # Game pygame.mixer.music.load("engine_files" + utils.sep + "music.ogg") pygame.mixer.music.play(1) # Do not loop the song, play it once seconds_counter = time.time() utils.text_colour = (190, 150, 200) while True: old_blow_points = blow_points if stage == 5: pygame.mixer.music.stop() end_anim(screen, True) utils.time_remaining = 0 # Make sure the game stops if time.time() - seconds_counter > 1: utils.time_remaining -= 1 seconds_counter = time.time() if utils.time_remaining > 0: utils.run_in_thread(get_data) utils.check_data_integrity(screen) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() screen.fill((0, 0, 0)) # Map the data coming from the microbit to a # scale of 0 to 100. # If the engine is not spinning, the pin is floating # due to the diode protection. Might need adjustement. blow = utils.map(utils.data[3], 80, 560, 0, 100) if blow > 70: blow_points += 0.02 if int(blow_points) > int(old_blow_points): stage += 1 utils.points += 1 temp_indicator.change_temp(stage) smoke.animate() screen.blit(background, (0, 0)) indicator_sprites.draw(screen) screen.blit(car, (X, Y)) smoke_sprites.draw(screen) smoke_sprites.update() indicator_sprites.update() # Info utils.draw_text(screen, "Blow on the fan!", utils.width / 2, 322) utils.draw_points(screen) utils.draw_time(screen, utils.time_remaining) utils.run_in_thread(utils.draw_volume(screen)) pygame.display.flip() utils.clock.tick(60) else: pygame.mixer.music.stop() if stage < 5: decrease_lives() end_anim(screen, False) utils.minigame_end(screen, get_data) break return