def export_slices(session_id: int): with application.app_context(): label_session = sessions.get_session_by_id(db.session, session_id) if label_session is None: print('Session with id {} not found'.format(session_id)) return session_slices_dir_path = os.path.join( EXPORTED_SLICES_DIR_PATH, label_session.session_name + ' Slices') session_slices_dir_path = inc_dir_name(session_slices_dir_path) os.makedirs(session_slices_dir_path, exist_ok=True) slices = sampling.get_slices_from_session(label_session) dataset = backend.get_dataset(label_session.dataset) for sl in slices: d_img = backend.get_image(dataset, sl.image_name) sl_max = backend.get_image_info(d_img)[1] sl_img = backend.get_slice(d_img, sl.slice_index, sl.slice_type, 0, sl_max) save_name = '{}_{}_{}.png'.format(sl.image_name, sl.slice_type.name, sl.slice_index) save_path = os.path.join(session_slices_dir_path, save_name) sl_img.save(save_path) print('Saved {}'.format(save_path))
def test_import_session_elements_length(self): dataset = backend.get_dataset('dataset1') session_json = { 'dataset': 'dataset1', 'session_name': 'session1', 'session_type': LabelSessionType.CATEGORICAL_IMAGE.name, 'prompt': 'test_prompt', 'label_values_str': 'l1,l2,l3', 'elements': [ '0,img1.nii.gz,None,None,None,None,None', '1,img2.nii,None,None,None,None,None', '2,img3,None,None,None,None,None', ] } sessions.import_session_json(db.session, dataset, 'session1', session_json) label_session = sessions.get_session_by_id(db.session, 1) element_count = len(label_session.elements) self.assertEqual(element_count, 3)
def test_create_comparison_slice_session_elements_metadata(self): dataset = backend.get_dataset('dataset1') comparisons = [(ImageSlice('img1.nii.gz', 0, SliceType.SAGITTAL), ImageSlice('img3', 1, SliceType.CORONAL)), (ImageSlice('img2.nii', 0, SliceType.SAGITTAL), ImageSlice('img3', 1, SliceType.AXIAL)), (ImageSlice('img2.nii', 255, SliceType.CORONAL), ImageSlice('img1.nii.gz', 100, SliceType.AXIAL))] sessions.create_comparison_slice_session(db.session, 'session1', 'test_prompt', dataset, ['l1', 'l2', 'l3'], comparisons) label_session = sessions.get_session_by_id(db.session, 1) session_elements = label_session.elements self.assertEqual(session_elements[0].image_1_name, 'img1.nii.gz') self.assertEqual(session_elements[0].image_2_name, 'img3') self.assertEqual(session_elements[1].slice_1_index, 0) self.assertEqual(session_elements[1].slice_2_index, 1) self.assertEqual(session_elements[2].slice_1_type, SliceType.CORONAL.name) self.assertEqual(session_elements[2].slice_2_type, SliceType.AXIAL.name)
def label_categorical_slice(): label_session_id = request.args.get('label_session', type=int, default=None) element_index = request.args.get('i', type=int, default=None) if label_session_id is None or element_index is None: abort(400) label_session = sessions.get_session_by_id(db.session, label_session_id) if label_session is None or label_session.session_type != LabelSessionType.CATEGORICAL_SLICE.name: abort(400) dataset = backend.get_dataset(label_session.dataset) if dataset is None: abort(400) element = labels.get_element_by_index(db.session, label_session, element_index) image = backend.get_image(dataset, element.image_1_name) if image is None: abort(400) im_slice = backend.ImageSlice(element.image_1_name, element.slice_1_index, backend.SliceType[element.slice_1_type]) _, max_value = backend.get_image_info(image) slice_label_value = element.current_label_value() return render_template('label_categorical_slice.html', label_session=label_session, dataset=dataset, element_id=element.id, image_slice=im_slice, slice_label_value=slice_label_value, image_max=max_value, previous_index=max(0, element_index - 1), next_index=min(label_session.element_count - 1, element_index + 1))
def create_categorical_slice_session(dataset_name: str): dataset = backend.get_dataset(dataset_name) if dataset is None: abort(400) current_sessions = sessions.get_sessions(db.session, dataset) label_session_count = len(current_sessions) form = CreateCategoricalSliceSessionForm(meta={'csrf': False}) comparison_sessions = sessions.get_sessions(db.session, dataset, LabelSessionType.COMPARISON_SLICE) for sess in comparison_sessions: form.comparisons.choices.append((str(sess.id), sess.session_name)) if form.validate_on_submit(): if form.session_name.data in [se.session_name for se in current_sessions]: form.session_name.errors.append('Session name already in use.') else: label_values = [v.strip() for v in form.label_values.data.split(',')] from_session = sessions.get_session_by_id(db.session, int(form.comparisons.data)) slices = sampling.get_slices_from_session(from_session) sessions.create_categorical_slice_session(db.session, form.session_name.data, form.prompt.data, dataset, label_values, slices) return redirect(url_for('dataset_overview', dataset_name=dataset.name)) return render_template('create_categorical_slice_session.html', dataset=dataset, label_session_count=label_session_count, form=form)
def test_get_slices_from_session_invalid_type(self): dataset = backend.get_dataset('dataset1') sessions.create_categorical_image_session(db.session, 'session1', 'prompt', dataset, ['l1', 'l2', 'l3']) label_session = sessions.get_session_by_id(db.session, 1) with self.assertRaises(ValueError): sampling.get_slices_from_session(label_session)
def session_overview(session_id: int): label_session = sessions.get_session_by_id(db.session, session_id) dataset = backend.get_dataset(label_session.dataset) has_thumbs = thumbnails.has_thumbnails(label_session) resume_point = None for session_element in label_session.elements: if len(session_element.labels) == 0: resume_point = session_element.element_index break if label_session.session_type == LabelSessionType.CATEGORICAL_IMAGE.name: images = backend.get_images(dataset) return render_template('session_overview_categorical.html', label_session=label_session, dataset=dataset, images=images, resume_point=resume_point, has_thumbs=has_thumbs) elif label_session.session_type == LabelSessionType.CATEGORICAL_SLICE.name: return render_template('session_overview_categorical_slice.html', label_session=label_session, dataset=dataset, resume_point=resume_point, has_thumbs=has_thumbs) else: # COMPARISON_SLICE return render_template('session_overview_comparison.html', label_session=label_session, dataset=dataset, resume_point=resume_point, has_thumbs=has_thumbs)
def test_get_session_by_id(self): dataset = backend.get_dataset('dataset1') sessions.create_categorical_image_session(db.session, 'session1', 'prompt', dataset, ['l1', 'l2', 'l3']) label_session = sessions.get_session_by_id(db.session, 1) self.assertEqual(label_session.session_name, 'session1')
def test_get_element_by_index(self): dataset = backend.get_dataset('dataset1') sessions.create_categorical_image_session(db.session, 'session1', 'prompt', dataset, ['l1', 'l2', 'l3']) label_session = sessions.get_session_by_id(db.session, 1) element = labels.get_element_by_index(db.session, label_session, 0) self.assertEqual(element.image_1_name, 'img1.nii.gz')
def test_get_all_labels_elements_length(self): dataset = backend.get_dataset('dataset1') sessions.create_categorical_image_session(db.session, 'session1', 'prompt', dataset, ['l1', 'l2', 'l3']) label_session = sessions.get_session_by_id(db.session, 1) all_labels = labels.get_all_labels(label_session) element_count = len(all_labels) self.assertEqual(element_count, 3)
def test_get_all_labels_elements_metadata(self): dataset = backend.get_dataset('dataset1') sessions.create_categorical_image_session(db.session, 'session1', 'prompt', dataset, ['l1', 'l2', 'l3']) label_session = sessions.get_session_by_id(db.session, 1) all_labels = labels.get_all_labels(label_session) check_elements = list(all_labels.keys()) self.assertEqual(check_elements, label_session.elements)
def test_export_session_json_elements_length(self): dataset = backend.get_dataset('dataset1') sessions.create_categorical_image_session(db.session, 'session1', 'test_prompt', dataset, ['l1', 'l2', 'l3']) label_session = sessions.get_session_by_id(db.session, 1) session_json = sessions.export_session_json(label_session) element_count = len(session_json['elements']) self.assertEqual(element_count, 3)
def export_session(session_id: int): label_session = sessions.get_session_by_id(db.session, session_id) if label_session is None: abort(400) session_bytes = sessions.export_session(label_session) return send_file(session_bytes, mimetype='application/json', as_attachment=True, attachment_filename=label_session.session_name + '.json', cache_timeout=0)
def slice_rankings(session_id: int): label_session = sessions.get_session_by_id(db.session, session_id) dataset = backend.get_dataset(label_session.dataset) ranked_slices = ranking.rank_slices(label_session) thumbnail_names = thumbnails.get_thumbnail_names(label_session) return render_template('slice_rankings.html', label_session=label_session, ranked_slices=ranked_slices, thumbnail_names=thumbnail_names)
def export_labels(session_id: int): label_session = sessions.get_session_by_id(db.session, session_id) if label_session is None: abort(400) labels_bytes = labels.export_labels(label_session) return send_file(labels_bytes, mimetype='text/csv', as_attachment=True, attachment_filename=label_session.session_name + ' Labels.csv', cache_timeout=0)
def test_create_categorical_image_session_metadata(self): dataset = backend.get_dataset('dataset1') sessions.create_categorical_image_session(db.session, 'session1', 'test_prompt', dataset, ['l1', 'l2', 'l3']) label_session = sessions.get_session_by_id(db.session, 1) self.assertEqual(label_session.session_name, 'session1') self.assertEqual(label_session.session_type, LabelSessionType.CATEGORICAL_IMAGE.name) self.assertEqual(label_session.prompt, 'test_prompt') self.assertEqual(label_session.dataset, 'dataset1') self.assertEqual(label_session.label_values_str, 'l1,l2,l3')
def test_create_comparison_slice_session_metadata(self): dataset = backend.get_dataset('dataset1') sessions.create_comparison_slice_session(db.session, 'session1', 'test_prompt', dataset, ['l1', 'l2', 'l3'], []) label_session = sessions.get_session_by_id(db.session, 1) self.assertEqual(label_session.session_name, 'session1') self.assertEqual(label_session.session_type, LabelSessionType.COMPARISON_SLICE.name) self.assertEqual(label_session.prompt, 'test_prompt') self.assertEqual(label_session.dataset, 'dataset1') self.assertEqual(label_session.label_values_str, 'l1,l2,l3')
def test_get_slices_from_session_categorical_slice(self): dataset = backend.get_dataset('dataset1') slices = [ ImageSlice('img1.nii.gz', 0, SliceType.SAGITTAL), ImageSlice('img1.nii.gz', 100, SliceType.SAGITTAL), ImageSlice('img2.nii', 1, SliceType.CORONAL), ImageSlice('img3', 255, SliceType.AXIAL) ] sessions.create_categorical_slice_session(db.session, 'session1', 'prompt', dataset, ['l1', 'l2', 'l3'], slices) label_session = sessions.get_session_by_id(db.session, 1) check_slices = sampling.get_slices_from_session(label_session) self.assertEqual(check_slices, slices)
def create_comparison_session(dataset_name: str): dataset = backend.get_dataset(dataset_name) if dataset is None: abort(400) current_sessions = sessions.get_sessions(db.session, dataset) label_session_count = len(current_sessions) images = backend.get_images(dataset) total_image_count = len(images) form = CreateComparisonSessionForm(meta={'csrf': False}) comparison_sessions = sessions.get_sessions(db.session, dataset, LabelSessionType.COMPARISON_SLICE) for sess in comparison_sessions: form.comparisons.choices.append((str(sess.id), sess.session_name)) form.image_count.validators = [ ComparisonNumberRange(min=1, max=total_image_count, message='Must be between %(min)s and %(max)s (the dataset size).') ] if form.validate_on_submit(): if form.session_name.data in [se.session_name for se in current_sessions]: form.session_name.errors.append('Session name already in use.') elif form.comparisons.data == 'create' and form.min_slice_percent.data >= form.max_slice_percent.data: form.max_slice_percent.errors.append('Max must be greater than min.') else: slice_type = backend.SliceType[form.slice_type.data] if form.comparisons.data == 'create': slices = sampling.sample_slices(dataset, slice_type, form.image_count.data, form.slice_count.data, form.min_slice_percent.data, form.max_slice_percent.data) if form.comparison_count.data is None: comparisons = sampling.all_comparisons(slices) else: comparisons = sampling.sample_comparisons(slices, form.comparison_count.data, form.max_comparisons_per_slice.data) else: from_session = sessions.get_session_by_id(db.session, int(form.comparisons.data)) comparisons = sampling.get_comparisons_from_session(from_session) label_values = [v.strip() for v in form.label_values.data.split(',')] sessions.create_comparison_slice_session(db.session, form.session_name.data, form.prompt.data, dataset, label_values, comparisons) return redirect(url_for('dataset_overview', dataset_name=dataset.name)) return render_template('create_comparison_session.html', dataset=dataset, label_session_count=label_session_count, total_image_count=total_image_count, form=form)
def test_get_ranking_contains_slices(self): dataset = backend.get_dataset('dataset1') comparisons = [ (ImageSlice('img1.nii.gz', 0, SliceType.SAGITTAL), ImageSlice('img3', 1, SliceType.CORONAL)), (ImageSlice('img2.nii', 0, SliceType.SAGITTAL), ImageSlice('img3', 1, SliceType.AXIAL)), (ImageSlice('img2.nii', 255, SliceType.CORONAL), ImageSlice('img1.nii.gz', 100, SliceType.AXIAL)) ] sessions.create_comparison_slice_session(db.session, 'session1', 'prompt', dataset, ['l1', 'l2'], comparisons) label_session = sessions.get_session_by_id(db.session, 1) ranked_slices = ranking.rank_slices(label_session) check_slices = sampling.get_slices_from_session(label_session) self.assertEqual(set(ranked_slices), set(check_slices))
def test_create_categorical_slice_session_elements_length(self): dataset = backend.get_dataset('dataset1') slices = [ ImageSlice('img1.nii.gz', 0, SliceType.SAGITTAL), ImageSlice('img1.nii.gz', 100, SliceType.SAGITTAL), ImageSlice('img2.nii', 1, SliceType.CORONAL), ImageSlice('img3', 255, SliceType.AXIAL) ] sessions.create_categorical_slice_session(db.session, 'session1', 'test_prompt', dataset, ['l1', 'l2', 'l3'], slices) label_session = sessions.get_session_by_id(db.session, 1) session_elements = label_session.elements session_element_count = len(session_elements) self.assertEqual(session_element_count, 4)
def test_get_all_labels_labels_length(self): dataset = backend.get_dataset('dataset1') sessions.create_categorical_image_session(db.session, 'session1', 'prompt', dataset, ['l1', 'l2', 'l3']) label_session = sessions.get_session_by_id(db.session, 1) labels.set_label(db.session, label_session.elements[0], 'l1', 1000) labels.set_label(db.session, label_session.elements[0], 'l2', 250) labels.set_label(db.session, label_session.elements[1], 'l3', 0) all_labels = labels.get_all_labels(label_session) check_labels = list(all_labels.values()) self.assertEqual(len(check_labels[0]), 2) self.assertEqual(len(check_labels[1]), 1) self.assertEqual(len(check_labels[2]), 0)
def test_get_slices_from_session_comparison_slice(self): dataset = backend.get_dataset('dataset1') slices = [ ImageSlice('img1.nii.gz', 0, SliceType.SAGITTAL), ImageSlice('img1.nii.gz', 100, SliceType.SAGITTAL), ImageSlice('img2.nii', 1, SliceType.CORONAL), ImageSlice('img3', 255, SliceType.AXIAL) ] comparisons = [(slices[0], slices[1]), (slices[2], slices[0]), (slices[3], slices[1])] sessions.create_comparison_slice_session(db.session, 'session1', 'prompt', dataset, ['l1', 'l2', 'l3'], comparisons) label_session = sessions.get_session_by_id(db.session, 1) check_slices = sampling.get_slices_from_session(label_session) # Note: Result from get_slices_by_session is sorted, so this relies on slices being defined in order above self.assertEqual(check_slices, slices)
def create_sort_session(dataset_name: str): dataset = backend.get_dataset(dataset_name) if dataset is None: abort(400) current_sessions = sessions.get_sessions(db.session, dataset) label_session_count = len(current_sessions) images = backend.get_images(dataset) total_image_count = len(images) form = CreateSortSessionForm(meta={'csrf': False}) form.image_count.validators = [ NumberRange(min=1, max=total_image_count, message='Must be between %(min)s and %(max)s (the dataset size).') ] for sess in sessions.get_sessions(db.session, dataset): t = sess.session_type if t in SLICE_SESSION_NAMES: form.slices_from.choices.append((str(sess.id), sess.session_name)) if form.validate_on_submit(): if form.session_name.data in [se.session_name for se in current_sessions]: form.session_name.errors.append('Session name already in use.') elif form.min_slice_percent.data >= form.max_slice_percent.data: form.max_slice_percent.errors.append('Max must be greater than min.') else: if form.slices_from.data == 'create': slice_type = backend.SliceType[form.slice_type.data] slices = sampling.sample_slices(dataset, slice_type, form.image_count.data, form.slice_count.data, form.min_slice_percent.data, form.max_slice_percent.data) else: from_session = sessions.get_session_by_id(db.session, int(form.slices_from.data)) slices = sampling.get_slices_from_session(from_session) sessions.create_sort_slice_session(db.session, form.session_name.data, form.prompt.data, dataset, slices) return redirect(url_for('dataset_overview', dataset_name=dataset.name)) return render_template('create_sort_session.html', dataset=dataset, label_session_count=label_session_count, total_image_count=total_image_count, form=form)
def label_compare(): label_session_id = request.args.get('label_session', type=int, default=None) comparison_index = request.args.get('i', type=int, default=None) if label_session_id is None or comparison_index is None: abort(400) assert 0 <= comparison_index label_session = sessions.get_session_by_id(db.session, label_session_id) if label_session is None or label_session.session_type != LabelSessionType.COMPARISON_SLICE.name: abort(400) dataset = backend.get_dataset(label_session.dataset) if dataset is None: abort(400) element = labels.get_element_by_index(db.session, label_session, comparison_index) slice_1 = backend.ImageSlice(element.image_1_name, element.slice_1_index, backend.SliceType[element.slice_1_type]) slice_2 = backend.ImageSlice(element.image_2_name, element.slice_2_index, backend.SliceType[element.slice_2_type]) image_1 = backend.get_image(dataset, slice_1.image_name) image_2 = backend.get_image(dataset, slice_2.image_name) _, image_1_max = backend.get_image_info(image_1) _, image_2_max = backend.get_image_info(image_2) current_label_value = element.current_label_value() return render_template('label_compare.html', label_session=label_session, prompt=label_session.prompt, dataset=dataset, element_id=element.id, slice_1=slice_1, slice_2=slice_2, image_1_max=image_1_max, image_2_max=image_2_max, current_label_value=current_label_value, sort_mode=False, previous_index=max(0, comparison_index - 1), next_index=min(label_session.element_count - 1, comparison_index + 1))
def test_import_session_metadata(self): dataset = backend.get_dataset('dataset1') session_json = { 'dataset': 'non_existent_dataset', 'session_name': 'session99', 'session_type': LabelSessionType.CATEGORICAL_IMAGE.name, 'prompt': 'test_prompt', 'label_values_str': 'l1,l2,l3', 'elements': [] } sessions.import_session_json(db.session, dataset, 'session1', session_json) label_session = sessions.get_session_by_id(db.session, 1) self.assertEqual(label_session.session_name, 'session1') self.assertEqual(label_session.session_type, LabelSessionType.CATEGORICAL_IMAGE.name) self.assertEqual(label_session.prompt, 'test_prompt') self.assertEqual(label_session.dataset, 'dataset1') self.assertEqual(label_session.label_values_str, 'l1,l2,l3')
def label_sort_compare(): label_session_id = request.args.get('label_session') if label_session_id is None: abort(404) label_session = sessions.get_session_by_id(db.session, label_session_id) if label_session is None: abort(404) if label_session.session_type != LabelSessionType.SORT_SLICE.name: abort(400) dataset = backend.get_dataset(label_session.dataset) if dataset is None: abort(404) complete, comparison_el, _ = comparesort.add_next_comparison(db.session, label_session) if complete: return redirect(url_for('session_overview', session_id=label_session.id)) comparison = sampling.get_comparison_from_element(comparison_el) slice_1, slice_2 = comparison image_1 = backend.get_image(dataset, slice_1.image_name) image_2 = backend.get_image(dataset, slice_2.image_name) _, image_1_max = backend.get_image_info(image_1) _, image_2_max = backend.get_image_info(image_2) current_label_value = None return render_template('label_compare.html', label_session=label_session, prompt=label_session.prompt, dataset=dataset, element_id=comparison_el.id, slice_1=slice_1, slice_2=slice_2, image_1_max=image_1_max, image_2_max=image_2_max, current_label_value=current_label_value, sort_mode=True)
def slice_rankings(session_id: int): label_session = sessions.get_session_by_id(db.session, session_id) if label_session.session_type == LabelSessionType.COMPARISON_SLICE.name: ranked_slices = ranking.rank_slices(label_session) elif label_session.session_type == LabelSessionType.SORT_SLICE.name: complete, _, sorted_slices = comparesort.add_next_comparison(db.session, label_session) if not complete: abort(400) ranked_slices = [(sl, None) for sl in reversed(sorted_slices)] else: abort(400) thumbs_data = thumbnails.get_thumbnails(label_session) num_thumbs_missing = len([d for d in thumbs_data.values() if not d.exists]) return render_template('slice_rankings.html', label_session=label_session, ranked_slices=ranked_slices, thumbs_data=thumbs_data, num_thumbs_missing=num_thumbs_missing)
def test_get_all_labels_labels_metadata(self): dataset = backend.get_dataset('dataset1') sessions.create_categorical_image_session(db.session, 'session1', 'prompt', dataset, ['l1', 'l2', 'l3']) label_session = sessions.get_session_by_id(db.session, 1) labels.set_label(db.session, label_session.elements[0], 'l1', 1000) labels.set_label(db.session, label_session.elements[0], 'l2', 250) labels.set_label(db.session, label_session.elements[1], 'l3', 0) all_labels = labels.get_all_labels(label_session) check_labels = list(all_labels.values()) self.assertEqual(check_labels[0][0].label_value, 'l1') self.assertEqual(check_labels[0][1].label_value, 'l2') self.assertEqual(check_labels[1][0].label_value, 'l3') self.assertEqual(check_labels[0][0].milliseconds, 1000) self.assertEqual(check_labels[0][1].milliseconds, 250) self.assertEqual(check_labels[1][0].milliseconds, 0)
def test_create_categorical_image_session_elements_metadata(self): dataset = backend.get_dataset('dataset1') sessions.create_categorical_image_session(db.session, 'session1', 'test_prompt', dataset, ['l1', 'l2', 'l3']) label_session = sessions.get_session_by_id(db.session, 1) session_elements = label_session.elements self.assertEqual(session_elements[0].element_index, 0) self.assertEqual(session_elements[1].element_index, 1) self.assertEqual(session_elements[2].element_index, 2) self.assertEqual(session_elements[0].image_1_name, 'img1.nii.gz') self.assertEqual(session_elements[1].image_1_name, 'img2.nii') self.assertEqual(session_elements[2].image_1_name, 'img3') self.assertIsNone(session_elements[0].slice_1_index) self.assertIsNone(session_elements[0].slice_1_type) self.assertIsNone(session_elements[0].image_2_name) self.assertIsNone(session_elements[0].slice_2_index) self.assertIsNone(session_elements[0].slice_2_type)