def test_split_and_open(): ''' split video ''' if not os.path.isdir(PATH_TO_OUTPUT_SPLIT): os.mkdir(PATH_TO_OUTPUT_SPLIT) print(PATH_TO_TEST_VIDEO) video_utils.split_video(PATH_TO_TEST_VIDEO, PATH_TO_OUTPUT_SPLIT) assert len(os.listdir(PATH_TO_OUTPUT_SPLIT)) == 4 ''' open path and read images ''' frames_array = video_utils.open_images(video_utils.read_folder(PATH_TO_OUTPUT_SPLIT)) assert len(frames_array) == 4 assert frames_array[0].shape == (768, 1024)
def test_camera_flow(tmpdir): video_utils.split_video(PATH_TO_TEST_VIDEO, tmpdir, fps=2) frames_array = [ cv2.cvtColor(cv2.imread(im_path), cv2.COLOR_BGR2GRAY) for im_path in video_utils.read_folder(tmpdir) ] camflow = camera_flow.CameraFlow() matrix = camflow.compute_transform_matrix(frames_array[0], frames_array[1]) assert matrix.shape == (2, 3) # test transform points point = np.array([448., 448.]) points = [] points.append(point) matrices = camflow.compute_transform_matrices(frames_array) for m in matrices: points.append(camflow.warp_coords(points[-1], m)) assert len(points) == 7 or len(points) == 6
def test_track(): if not os.path.isdir(PATH_TO_OUTPUT_SPLIT) or len(os.listdir(PATH_TO_OUTPUT_SPLIT)) != 4: video_utils.split_video(PATH_TO_TEST_VIDEO, PATH_TO_OUTPUT_SPLIT) frames_array = video_utils.open_images(video_utils.read_folder(PATH_TO_OUTPUT_SPLIT)) camflow = tracker.CameraFlow() matrix = camflow.compute_transform_matrix(frames_array[0], frames_array[1]) assert matrix.shape == (2, 3) ''' transform points ''' point = np.array([448., 448.]) points = [] points.append(point) matrices = camflow.compute_transform_matrices(frames_array) for m in matrices: points.append(camflow.warp_coords(points[-1], m)) assert len(points) == 4 print(points)
def handle_file(file: FileStorage, upload_folder=UPLOAD_FOLDER, fps=FPS, resolution=RESOLUTION) -> Dict[str, np.array]: """Make the prediction if the data is coming from an uploaded file. Arguments: - *file*: The file, can be either an image or a video - *upload_folder*: Where the files are temporarly stored Returns: - for an image: a json of format ```json { "image": filename, "detected_trash": [ { "box": [1, 1, 2, 20], "label": "fragments", "score": 0.92 }, { "box": [10, 10, 25, 20], "label": "bottles", "score": 0.75 } ] } ``` - for a video: a json of format ```json { "video_length": 132, "fps": 2, "video_id": "GOPRO1234.mp4", "detected_trash": [ { "label": "bottles", "id": 0, "frame_to_box": { 23: [0, 0, 1, 10], 24: [1, 1, 4, 13] } }, { "label": "fragments", "id": 1, "frame_to_box": { 12: [10, 8, 9, 15] } } ] } ``` Raises: - *NotImplementedError*: If the format of data isn't handled yet """ filename = secure_filename(file.filename) full_filepath = os.path.join(upload_folder, filename) if not os.path.isdir(upload_folder): os.mkdir(upload_folder) if os.path.isfile(full_filepath): os.remove(full_filepath) file.save(full_filepath) file_type = file.mimetype.split("/")[ 0] # mimetype is for example 'image/png' and we only want the image if file_type == "image": image = cv2.imread(full_filepath) # cv2 opens in BGR os.remove(full_filepath) # remove it as we don't need it anymore return { "image": filename, "detected_trash": predict_and_format_image(image) } elif file_type in ["video", "application"]: # splitting video and saving frames folder = os.path.join(upload_folder, "{}_split".format(filename)) if os.path.isdir(folder): shutil.rmtree(folder) os.mkdir(folder) logger.info("Splitting video {} to {}.".format(full_filepath, folder)) split_video(full_filepath, folder, fps=fps, resolution=resolution) image_paths = read_folder(folder) if len(image_paths) == 0: raise ValueError("No output image") # making inference on frames logger.info("{} images to analyze on {} CPUs.".format( len(image_paths), CPU_COUNT)) with multiprocessing.Pool(CPU_COUNT) as p: inference_outputs = list( tqdm( p.imap(process_image, image_paths), total=len(image_paths), )) logger.info("Finish analyzing video {}.".format(full_filepath)) # tracking objects logger.info("Starting tracking.") object_tracker = ObjectTracking(filename, image_paths, inference_outputs, fps=fps) logger.info("Tracking finished.") return object_tracker.json_result() else: raise NotImplementedError(file_type)
def handle_file(file: FileStorage, upload_folder: str = UPLOAD_FOLDER, fps: int = FPS, resolution: Tuple[int, int] = RESOLUTION, **kwargs) -> Dict[str, np.array]: """Make the prediction if the data is coming from an uploaded file. Arguments: - *file*: The file, can be either an image or a video, or a zipped folder - *upload_folder*: Where the files are temporarly stored Returns: - for an image: a json of format ```json { "image": filename, "detected_trash": [ { "box": [1, 1, 2, 20], "label": "fragments", "score": 0.92 }, { "box": [10, 10, 25, 20], "label": "bottles", "score": 0.75 } ] } ``` - for a video or a zipped file: a json of format ```json { "video_length": 132, "fps": 2, "video_id": "GOPRO1234.mp4", "detected_trash": [ { "label": "bottles", "id": 0, "frame_to_box": { 23: [0, 0, 1, 10], 24: [1, 1, 4, 13] } }, { "label": "fragments", "id": 1, "frame_to_box": { 12: [10, 8, 9, 15] } } ] } ``` Raises: - *NotImplementedError*: If the format of data isn't handled yet """ if kwargs: logger.warning("Unused kwargs: {}".format(kwargs)) filename = secure_filename(file.filename) full_filepath = os.path.join(upload_folder, filename) if not os.path.isdir(upload_folder): os.mkdir(upload_folder) if os.path.isfile(full_filepath): os.remove(full_filepath) file.save(full_filepath) file_type = file.mimetype.split("/")[0] # mimetype is for example 'image/png' and we only want the image if file_type == "image": image = cv2.imread(full_filepath) # cv2 opens in BGR os.remove(full_filepath) # remove it as we don't need it anymore try: detected_trash = predict_and_format_image(image) except ValueError as e: return {"error": str(e)} return {"image": filename, "detected_trash": detected_trash} elif file_type in ["video", "application"]: folder = None if file.mimetype == "application/zip": # zip case ZipFile(full_filepath).extractall(upload_folder) dirname = None with ZipFile(full_filepath, 'r') as zipObj: listOfFileNames = zipObj.namelist() for fileName in listOfFileNames: dirname = os.path.dirname(fileName) zipObj.extract(fileName, upload_folder) folder = os.path.join(upload_folder, dirname) else: # video case: splitting video and saving frames folder = os.path.join(upload_folder, "{}_split".format(filename)) if os.path.isdir(folder): shutil.rmtree(folder) os.mkdir(folder) logger.info("Splitting video {} to {}.".format( full_filepath, folder)) split_video(full_filepath, folder, fps=fps, resolution=resolution) print("folder:", folder, "uplaod_folder:", upload_folder, "file.filename:", file.filename) image_paths = read_folder(folder) if len(image_paths) == 0: raise ValueError("No output image") # making inference on frames logger.info("{} images to analyze on {} CPUs.".format( len(image_paths), CPU_COUNT)) try: with multiprocessing.Pool(CPU_COUNT) as p: inference_outputs = list( tqdm( p.imap(process_image, image_paths), total=len(image_paths), )) except ValueError as e: return {"error": str(e)} logger.info("Finish analyzing video {}.".format(full_filepath)) # tracking objects logger.info("Starting tracking.") object_tracker = ObjectTracking(filename, image_paths, inference_outputs, fps=fps) tracks = object_tracker.compute_tracks() logger.info("Tracking finished.") return object_tracker.json_result(tracks) else: raise NotImplementedError(file_type)