def test_fuse_image_create_vector(tmpdir): tmpdir = Path(tmpdir) projects = sa.search_projects(PROJECT_NAME_VECTOR, return_metadata=True) for project in projects: sa.delete_project(project) project = sa.create_project(PROJECT_NAME_VECTOR, "test", "Vector") sa.upload_image_to_project( project, "./tests/sample_project_vector/example_image_1.jpg", annotation_status="QualityCheck" ) sa.create_annotation_classes_from_classes_json( project, "./tests/sample_project_vector/classes/classes.json" ) sa.add_annotation_bbox_to_image( project, "example_image_1.jpg", [20, 20, 40, 40], "Human" ) sa.add_annotation_polygon_to_image( project, "example_image_1.jpg", [60, 60, 100, 100, 80, 100], "Personal vehicle" ) sa.add_annotation_polyline_to_image( project, "example_image_1.jpg", [200, 200, 300, 200, 350, 300], "Personal vehicle" ) sa.add_annotation_point_to_image( project, "example_image_1.jpg", [400, 400], "Personal vehicle" ) sa.add_annotation_ellipse_to_image( project, "example_image_1.jpg", [600, 600, 50, 100, 20], "Personal vehicle" ) sa.add_annotation_template_to_image( project, "example_image_1.jpg", [600, 300, 600, 350, 550, 250, 650, 250, 550, 400, 650, 400], [1, 2, 3, 1, 4, 1, 5, 2, 6, 2], "Human" ) sa.add_annotation_cuboid_to_image( project, "example_image_1.jpg", [60, 300, 200, 350, 120, 325, 250, 500], "Human" ) export = sa.prepare_export(project, include_fuse=True) (tmpdir / "export").mkdir() sa.download_export(project, export, (tmpdir / "export")) # sa.create_fuse_image( # "./tests/sample_project_vector/example_image_1.jpg", # "./tests/sample_project_vector/classes/classes.json", "Vector" # ) paths = sa.download_image( project, "example_image_1.jpg", tmpdir, include_annotations=True, include_fuse=True, include_overlay=True ) im1 = Image.open(tmpdir / "export" / "example_image_1.jpg___fuse.png") im1_array = np.array(im1) im2 = Image.open(paths[2][0]) im2_array = np.array(im2) assert im1_array.shape == im2_array.shape assert im1_array.dtype == im2_array.dtype
def test_basic_images(project_type, name, description, from_folder, tmpdir): tmpdir = Path(tmpdir) projects_found = sa.search_projects(name, return_metadata=True) for pr in projects_found: sa.delete_project(pr) projects_found = sa.search_projects(name, return_metadata=True) project = sa.create_project(name, description, project_type) sa.upload_images_from_folder_to_project(project, from_folder, annotation_status="InProgress") sa.create_annotation_classes_from_classes_json( project, from_folder / "classes" / "classes.json") images = sa.search_images(project, "example_image_1") assert len(images) == 1 image_name = images[0] sa.download_image(project, image_name, tmpdir, True) # assert sa.get_image_preannotations(project, image_name # )["preannotation_json_filename"] is None assert len( sa.get_image_annotations( project, image_name)["annotation_json"]["instances"]) == 0 sa.download_image_annotations(project, image_name, tmpdir) assert len(list(Path(tmpdir).glob("*"))) == 2 # sa.download_image_preannotations(project, image_name, tmpdir) # assert len(list(Path(tmpdir).glob("*"))) == 2 assert (Path(tmpdir) / image_name).is_file() sa.upload_image_annotations( project, image_name, sa.image_path_to_annotation_paths(from_folder / image_name, project_type)[0], None if project_type == "Vector" else sa.image_path_to_annotation_paths(from_folder / image_name, project_type)[1]) assert sa.get_image_annotations( project, image_name)["annotation_json_filename"] is not None sa.download_image_annotations(project, image_name, tmpdir) annotation = list(Path(tmpdir).glob("*.json")) assert len(annotation) == 1 annotation = json.load(open(annotation[0])) sa.download_annotation_classes_json(project, tmpdir) downloaded_classes = json.load(open(tmpdir / "classes.json")) for a in annotation: if "className" not in a: continue for c1 in downloaded_classes: if a["className"] == c1["name"] or a[ "className"] == "Personal vehicle1": # "Personal vehicle1" is not existing class in annotations break else: assert False input_classes = json.load(open(from_folder / "classes" / "classes.json")) assert len(downloaded_classes) == len(input_classes) for c1 in downloaded_classes: found = False for c2 in input_classes: if c1["name"] == c2["name"]: found = True break assert found sa.delete_project(project)
def test_add_bbox(tmpdir): tmpdir = Path(tmpdir) projects_found = sa.search_projects(PROJECT_NAME, return_metadata=True) for pr in projects_found: if pr["name"] == PROJECT_NAME: sa.delete_project(pr) project = sa.create_project(PROJECT_NAME, PROJECT_DESCRIPTION, "Vector") sa.upload_images_from_folder_to_project( PROJECT_NAME, PATH_TO_SAMPLE_PROJECT, annotation_status="InProgress" ) sa.create_annotation_classes_from_classes_json( project, PATH_TO_SAMPLE_PROJECT / "classes" / "classes.json" ) sa.create_annotation_class( project, "test_add", "#FF0000", [ { "name": "height", "attributes": [{ "name": "tall" }, { "name": "short" }] } ] ) sa.upload_annotations_from_folder_to_project( project, PATH_TO_SAMPLE_PROJECT ) images = sa.search_images(project, "example_image_1") image_name = images[0] annotations = sa.get_image_annotations(project, image_name)["annotation_json"] sa.add_annotation_bbox_to_image( project, image_name, [10, 10, 500, 100], "test_add" ) sa.add_annotation_polyline_to_image( project, image_name, [110, 110, 510, 510, 600, 510], "test_add" ) sa.add_annotation_polygon_to_image( project, image_name, [100, 100, 500, 500, 200, 300], "test_add", [{ "name": "tall", "groupName": "height" }] ) sa.add_annotation_point_to_image( project, image_name, [250, 250], "test_add" ) sa.add_annotation_ellipse_to_image( project, image_name, [405, 405, 20, 70, 15], "test_add" ) sa.add_annotation_template_to_image( project, image_name, [600, 30, 630, 30, 615, 60], [1, 3, 2, 3], "test_add" ) sa.add_annotation_cuboid_to_image( project, image_name, [800, 500, 900, 600, 850, 450, 950, 700], "test_add" ) sa.add_annotation_comment_to_image( project, image_name, "hey", [100, 100], "*****@*****.**", True ) annotations_new = sa.get_image_annotations(project, image_name)["annotation_json"] json.dump(annotations_new, open(tmpdir / "new_anns.json", "w")) assert len(annotations_new) == len(annotations) + 8 export = sa.prepare_export(project, include_fuse=True) sa.download_export(project, export, tmpdir) df = sa.aggregate_annotations_as_df(tmpdir) num = len(df[df["imageName"] == image_name]["instanceId"].dropna().unique()) assert num == len( annotations ) - 6 + 7 # -6 for 3 comments and 3 invalid annotations, className or attributes
def test_basic_folders(tmpdir): PROJECT_NAME = "test folder simple" tmpdir = Path(tmpdir) projects_found = sa.search_projects(PROJECT_NAME, return_metadata=True) for pr in projects_found: sa.delete_project(pr) project = sa.create_project(PROJECT_NAME, 'test', 'Vector') project = project["name"] sa.upload_images_from_folder_to_project(project, FROM_FOLDER, annotation_status="InProgress") images = sa.search_images(project, "example_image_1") assert len(images) == 1 folders = sa.search_folders(project) assert len(folders) == 0 folder_metadata = sa.create_folder(project, "folder1") assert folder_metadata["name"] == "folder1" folders = sa.search_folders(project, return_metadata=True) assert len(folders) == 1 assert folders[0]["name"] == "folder1" folders = sa.search_folders(project) assert len(folders) == 1 assert folders[0] == "folder1" images = sa.search_images(project + "/folder1", "example_image_1") assert len(images) == 0 images = sa.search_images_all_folders(project, "example_image_1") assert len(images) == 1 folder = sa.get_folder_metadata(project, "folder1") assert isinstance(folder, dict) assert folder["name"] == "folder1" with pytest.raises(SABaseException) as e: folder = sa.get_folder_metadata(project, "folder2") assert 'Folder not found' in str(e) sa.upload_images_from_folder_to_project(project + "/folder1", FROM_FOLDER, annotation_status="InProgress") images = sa.search_images(project + "/folder1", "example_image_1") assert len(images) == 1 sa.upload_images_from_folder_to_project(project + "/folder1", FROM_FOLDER, annotation_status="InProgress") images = sa.search_images(project + "/folder1") assert len(images) == 4 with pytest.raises(SABaseException) as e: sa.upload_images_from_folder_to_project(project + "/folder2", FROM_FOLDER, annotation_status="InProgress") assert 'Folder not found' in str(e) folder_metadata = sa.create_folder(project, "folder2") assert folder_metadata["name"] == "folder2" folders = sa.search_folders(project) assert len(folders) == 2 folders = sa.search_folders(project, folder_name="folder") assert len(folders) == 2 folders = sa.search_folders(project, folder_name="folder2") assert len(folders) == 1 assert folders[0] == "folder2" folders = sa.search_folders(project, folder_name="folder1") assert len(folders) == 1 assert folders[0] == "folder1" folders = sa.search_folders(project, folder_name="old") assert len(folders) == 2
def test_create_like_project(tmpdir): tmpdir = Path(tmpdir) projects = sa.search_projects(PROJECT_NAME, return_metadata=True) for project in projects: sa.delete_project(project) sa.create_project(PROJECT_NAME, "tt", "Vector") sa.create_annotation_class( PROJECT_NAME, "rrr", "#FFAAFF", [{ "name": "tall", "is_multiselect": 0, "attributes": [{ "name": "yes" }, { "name": "no" }] }, { "name": "age", "is_multiselect": 0, "attributes": [{ "name": "young" }, { "name": "old" }] }]) old_settings = sa.get_project_settings(PROJECT_NAME) for setting in old_settings: if "attribute" in setting and setting["attribute"] == "Brightness": brightness_value = setting["value"] sa.set_project_settings(PROJECT_NAME, [{ "attribute": "Brightness", "value": brightness_value + 10 }]) sa.set_project_workflow(PROJECT_NAME, [{ "step": 1, "className": "rrr", "tool": 3, "attribute": [{ "attribute": { "name": "young", "attribute_group": { "name": "age" } } }, { "attribute": { "name": "yes", "attribute_group": { "name": "tall" } } }] }]) users = sa.search_team_contributors() sa.share_project(PROJECT_NAME, users[1], "QA") projects = sa.search_projects(PROJECT_NAME2, return_metadata=True) for project in projects: sa.delete_project(project) new_project = sa.clone_project(PROJECT_NAME2, PROJECT_NAME, copy_contributors=True) assert new_project["description"] == "tt" assert new_project["type"] == "Vector" time.sleep(1) ann_classes = sa.search_annotation_classes(PROJECT_NAME2) assert len(ann_classes) == 1 assert ann_classes[0]["name"] == "rrr" assert ann_classes[0]["color"] == "#FFAAFF" new_settings = sa.get_project_settings(PROJECT_NAME2) for setting in new_settings: if "attribute" in setting and setting["attribute"] == "Brightness": new_brightness_value = setting["value"] assert new_brightness_value == brightness_value + 10 new_workflow = sa.get_project_workflow(PROJECT_NAME2) assert len(new_workflow) == 1 assert new_workflow[0]["className"] == "rrr" assert new_workflow[0]["tool"] == 3 assert len(new_workflow[0]["attribute"]) == 2 assert new_workflow[0]["attribute"][0]["attribute"]["name"] == "young" assert new_workflow[0]["attribute"][0]["attribute"]["attribute_group"][ "name"] == "age" assert new_workflow[0]["attribute"][1]["attribute"]["name"] == "yes" assert new_workflow[0]["attribute"][1]["attribute"]["attribute_group"][ "name"] == "tall" new_project = sa.get_project_metadata(new_project["name"], include_contributors=True) assert len(new_project["contributors"]) == 1 assert new_project["contributors"][0]["user_id"] == users[1] assert new_project["contributors"][0]["user_role"] == "QA"
def test_basic_project(project_type, name, description, from_folder, tmpdir): tmpdir = Path(tmpdir) projects_found = sa.search_projects(name, return_metadata=True) for pr in projects_found: sa.delete_project(pr) projects_found = sa.search_projects(name, return_metadata=True) assert len(projects_found) == 0 project = sa.create_project(name, description, project_type) assert project["name"] == name assert project["description"] == description assert project["type"] == sa.project_type_str_to_int(project_type) projects_found = sa.search_projects(name) assert len(projects_found) == 1 assert projects_found[0] == name sa.upload_images_from_folder_to_project(project, from_folder, annotation_status="InProgress") count_in_folder = len(list(from_folder.glob("*.jpg"))) + len( list(from_folder.glob("*.png"))) count_in_folder -= len(list(from_folder.glob("*___fuse.png"))) if project_type == "Pixel": count_in_folder -= len(list(from_folder.glob("*___save.png"))) images = sa.search_images(project) assert count_in_folder == len(images) sa.create_annotation_classes_from_classes_json( project, from_folder / "classes" / "classes.json") classes_in_file = json.load(open(from_folder / "classes" / "classes.json")) classes_in_project = sa.search_annotation_classes(project, return_metadata=True) json.dump(classes_in_project, open(Path(tmpdir) / "tmp_c.json", 'w')) assert len(classes_in_file) == len(classes_in_project) for cl_f in classes_in_file: found = False for cl_c in classes_in_project: if cl_f["name"] == cl_c["name"]: found = True break assert found sa.upload_annotations_from_folder_to_project(project, from_folder) export = sa.prepare_export(project) sa.download_export(project, export, tmpdir) for image in from_folder.glob("*.[jpg|png]"): found = False for image_in_project in tmpdir.glob("*.jpg"): if image.name == image_in_project.name: found = True break assert found, image for json_in_folder in from_folder.glob("*.json"): found = False for json_in_project in tmpdir.glob("*.json"): if json_in_folder.name == json_in_project.name: found = True break assert found, json_in_folder if project_type == "Pixel": for mask_in_folder in from_folder.glob("*___save.png"): found = False for mask_in_project in tmpdir.glob("*___save.png"): if mask_in_folder.name == mask_in_project.name: found = True break assert found, mask_in_folder