def test_list(self): with deepstar_path(): VideoModel().insert('test1', 'test2') FrameSetModel().insert(1) frame_model = FrameModel() frame_model.insert(1, 0) frame_model.insert(1, 1) frame_model.insert(1, 0) result = frame_model.list(1) self.assertEqual(len(result), 3) self.assertEqual(result[0], (1, 1, 0)) self.assertEqual(result[1], (2, 1, 1)) self.assertEqual(result[2], (3, 1, 0)) result = frame_model.list(1, length=2) self.assertEqual(len(result), 2) self.assertEqual(result[0], (1, 1, 0)) self.assertEqual(result[1], (2, 1, 1)) result = frame_model.list(1, offset=1) self.assertEqual(len(result), 2) self.assertEqual(result[0], (2, 1, 1)) self.assertEqual(result[1], (3, 1, 0)) result = frame_model.list(1, length=1, offset=1) self.assertEqual(len(result), 1) self.assertEqual(result[0], (2, 1, 1)) result = frame_model.list(1, rejected=False) self.assertEqual(len(result), 2) self.assertEqual(result[0], (1, 1, 0)) self.assertEqual(result[1], (3, 1, 0))
def test_fk_frame_sets_on_delete_cascade(self): with deepstar_path(): frame_set_model = FrameSetModel() frame_set_model.insert(1) frame_model = FrameModel() frame_model.insert(1, 0) self.assertEqual(frame_model.list(1), [(1, 1, 0)]) frame_set_model.delete(1) self.assertIsNone(frame_model.list(1))
def test_select(self): with deepstar_path(): VideoModel().insert('test1', 'test2') FrameSetModel().insert(1) frame_model = FrameModel() frame_model.insert(1, 0) result = frame_model.select(1) self.assertEqual(result, (1, 1, 0))
def test_count_rejected_false(self): with deepstar_path(): VideoModel().insert('test1', 'test2') FrameSetModel().insert(1) frame_model = FrameModel() frame_model.insert(1, 0) frame_model.insert(1, 1) frame_model.insert(1, 0) self.assertEqual(frame_model.count(1, rejected=False), 2)
def test_count(self): with deepstar_path(): VideoModel().insert('test1', 'test2') FrameSetModel().insert(1) frame_model = FrameModel() frame_model.insert(1, 0) frame_model.insert(1, 0) frame_model.insert(1, 0) self.assertEqual(frame_model.count(1), 3)
def test_count_rejected_false(self): with deepstar_path(): FrameSetModel().insert(None) frame_model = FrameModel() frame_model.insert(1, 0) frame_model.insert(1, 0) frame_model.insert(1, 0) TransformSetModel().insert('test', 1) transform_model = TransformModel() transform_model.insert(1, 1, '{}', 0) transform_model.insert(1, 2, '{}', 1) transform_model.insert(1, 3, '{}', 0) self.assertEqual(transform_model.count(1, rejected=False), 2)
def test_count(self): with deepstar_path(): FrameSetModel().insert(None) frame_model = FrameModel() frame_model.insert(1, 0) frame_model.insert(1, 0) frame_model.insert(1, 0) TransformSetModel().insert('test', 1) transform_model = TransformModel() transform_model.insert(1, 1, '{}', 0) transform_model.insert(1, 2, '{}', 0) transform_model.insert(1, 3, '{}', 0) self.assertEqual(frame_model.count(1), 3)
def insert_images(self, images_path, opts): """ This method inserts a frame set from a directory of images. :param str images_path: The path to the directory containing the images to insert. :param dict opts: The dict of options. :raises: CommandLineRouteHandlerError :rtype: None """ if not os.path.isdir(images_path): raise CommandLineRouteHandlerError( f'The path at {images_path} is not a directory') frame_set_id = FrameSetModel().insert(None) p1 = FrameSetSubDir.path(frame_set_id) os.makedirs(p1) frame_model = FrameModel() for image_path in glob.glob(os.path.join(images_path, '*')): ext = os.path.splitext(image_path)[1].lower() if ext not in ['.jpg', '.png']: debug( f"Skipped image at {image_path} because it does not " f"have a '.jpg' or '.png' file extension", 4) continue image = cv2.imread(image_path) frame_id = frame_model.insert(frame_set_id, 0) p2 = FrameFile.path(p1, frame_id, 'jpg') cv2.imwrite(p2, image, [cv2.IMWRITE_JPEG_QUALITY, 100]) thumbnail = imutils.resize(image, width=192, height=192) p3 = FrameFile.path(p1, frame_id, 'jpg', '192x192') cv2.imwrite(p3, thumbnail, [cv2.IMWRITE_JPEG_QUALITY, 100]) debug( f'Image at {image_path} inserted with ID {frame_id:08d} at ' f'{p2} and {p3}', 4) debug(f'frame_set_id={frame_set_id}, fk_videos=None', 3)
def select_merge(self, frame_set_ids, video_id=None, rejected=False): """ This method merges multiple frame sets into one frame set. :param list(int) frame_set_ids: The frame set IDs. :param int video_id: The video ID to which this frame set corresponds (if any). The default value is None. :param bool rejected: True if should include rejected frames else False if should not. The default value is False. :raises: CommandLineRouteHandlerError :rtype: None """ frame_set_model = FrameSetModel() for frame_set_id in frame_set_ids: result = frame_set_model.select(frame_set_id) if result is None: raise CommandLineRouteHandlerError( f'Frame set with ID {frame_set_id:08d} not found') frame_set_id = frame_set_model.insert(video_id) p1 = FrameSetSubDir.path(frame_set_id) os.makedirs(p1) frame_model = FrameModel() length = int(os.environ.get('MODEL_LIST_LENGTH', '100')) for frame_set_id_ in frame_set_ids: offset = 0 p2 = FrameSetSubDir.path(frame_set_id_) while True: frames = frame_model.list(frame_set_id_, length=length, offset=offset, rejected=rejected) if not frames: break for frame in frames: frame_id = frame_model.insert(frame_set_id, frame[2]) p3 = FrameFile.path(p2, frame[0], 'jpg') p4 = FrameFile.path(p2, frame[0], 'jpg', '192x192') p5 = FrameFile.path(p1, frame_id, 'jpg') p6 = FrameFile.path(p1, frame_id, 'jpg', '192x192') shutil.copy(p3, p5) shutil.copy(p4, p6) debug( f'Frame with ID {frame[0]:08d} and thumbnail at ' f'{p3} and {p4} merged as ID {frame_id:08d} at ' f'{p5} and {p6}', 4) offset += length debug(f'frame_set_id={frame_set_id}, fk_videos={video_id}', 3)
def video_select_extract(self, video_id, sub_sample=1, max_sample=0): """ This method extracts frames and thumbnails from a video to a frame set. :param int video_id: The video ID. :param int sub_sample: Sample frames at a rate of 1 sample per sub_sample rate. For example, if sub_sample is 30, then sample frames at a rate of 1 frame per 30 frames. The default value of 1 indicates to sample every frame. :param int max_sample: Sample up to maximum count of frames. For example, sample up to 1000 total frames (and then cease to sample). The default value of 0 indicates that there is no maximum count of frames. :raises: CommandLineRouteHandlerError :rtype: int """ result = VideoModel().select(video_id) p1 = VideoFile.path(result[2]) vc = cv2.VideoCapture(p1) try: if not vc.isOpened(): raise CommandLineRouteHandlerError( f'OpenCV VideoCapture isOpened returned false for {p1}') frame_set_id = FrameSetModel().insert(video_id) p2 = FrameSetSubDir.path(frame_set_id) os.makedirs(p2) frame_model = FrameModel() sub_sample_ = sub_sample max_sample_ = 0 while True: ret, frame = vc.read() if not ret: break # sub_sample if sub_sample_ != sub_sample: sub_sample_ += 1 continue else: sub_sample_ = 1 frame_id = frame_model.insert(frame_set_id, 0) p3 = FrameFile.path(p2, frame_id, 'jpg') cv2.imwrite(p3, frame, [cv2.IMWRITE_JPEG_QUALITY, 100]) # imutils.resize preserves aspect ratio. thumbnail = imutils.resize(frame, width=192, height=192) p4 = FrameFile.path(p2, frame_id, 'jpg', '192x192') # can adjust jpeg quality thus impacting file size cv2.imwrite(p4, thumbnail, [cv2.IMWRITE_JPEG_QUALITY, 100]) debug( f'Frame with ID {frame_id:08d} and thumbnail extracted ' f'to {p3} and {p4}', 4) # max_sample max_sample_ += 1 if max_sample > 0: if max_sample_ == max_sample: break finally: vc.release() return frame_set_id