def testDetectSquares(self): image = np.zeros((200, 250), dtype=np.uint8) image = draw_square_by_corner(image, 10, (10, 10), 85) image = draw_square_by_corner(image, 30, (10, 90), 85) image = draw_square_by_corner(image, 50, (70, 150), 190) image = draw_square_by_corner(image, 20, (130, 50), 190) image = draw_square_by_corner(image, 15, (50, 150), 255) builder = SSLWorkflowBuilder() builder.set_segmenter(BasicSemanticSegmenter()) builder.set_default_tile_builder() builder.set_tile_size(100, 90) builder.set_background_class(0) workflow = builder.get() results = workflow.process(NumpyImage(image)) self.assertEqual(len(results), 5) idx = np.argsort([p.area for p in results.polygons]) self.assertEqual(100, int(results.polygons[idx[0]].area)) self.assertEqual(225, int(results.polygons[idx[1]].area)) self.assertEqual(400, int(results.polygons[idx[2]].area)) self.assertEqual(900, int(results.polygons[idx[3]].area)) self.assertEqual(2500, int(results.polygons[idx[4]].area)) self.assertEqual(85, results.labels[idx[0]]) self.assertEqual(255, results.labels[idx[1]]) self.assertEqual(190, results.labels[idx[2]]) self.assertEqual(85, results.labels[idx[3]]) self.assertEqual(190, results.labels[idx[4]])
def testWorkflowChainBuilder(self): segmenter = DumbSegmenter() dispatcher = DumbDispatcher() classifier = DumbClassifier() builder = SLDCWorkflowBuilder() builder.set_segmenter(segmenter) builder.set_default_tile_builder() builder.set_one_shot_dispatcher(dispatcher, {"default": classifier}) workflow1 = builder.get() builder2 = SSLWorkflowBuilder() builder2.set_segmenter(segmenter) builder2.set_default_tile_builder() workflow2 = builder2.get() _filter = DefaultFilter() logger = StandardOutputLogger(Logger.DEBUG) chain_builder = WorkflowChainBuilder() chain_builder.set_logger(logger) with self.assertRaises(MissingComponentException): chain_builder.get() chain_builder.set_first_workflow(workflow1, label="first") chain_builder.add_executor(workflow2, label="second", filter=_filter, n_jobs=2, logger=logger) chain = chain_builder.get() self.assertIsInstance(chain, WorkflowChain) self.assertEqual(chain.logger, logger) self.assertEqual(chain._first_workflow, workflow1) self.assertEqual(len(chain._executors), 1) self.assertEqual(chain._executors[0]._workflow, workflow2) self.assertEqual(len(chain._labels), 2) self.assertEqual(tuple(chain._labels), ("first", "second")) self.assertEqual(len(chain._filters), 1) self.assertEqual(chain._filters[0], _filter)
def testDetectSquaresParallel(self): image = np.zeros((200, 250), dtype=np.uint8) image = draw_square_by_corner(image, 10, (10, 10), 85) image = draw_square_by_corner(image, 30, (10, 90), 85) image = draw_square_by_corner(image, 50, (70, 150), 190) image = draw_square_by_corner(image, 20, (130, 50), 190) image = draw_square_by_corner(image, 15, (50, 150), 255) builder = SSLWorkflowBuilder() builder.set_segmenter(BasicSemanticSegmenter()) builder.set_default_tile_builder() builder.set_tile_size(100, 90) builder.set_background_class(0) builder.set_n_jobs(2) workflow = builder.get() results = workflow.process(NumpyImage(image)) self.assertEqual(len(results), 5) idx = np.argsort([p.area for p in results.polygons]) self.assertEqual(100, int(results.polygons[idx[0]].area)) self.assertEqual(225, int(results.polygons[idx[1]].area)) self.assertEqual(400, int(results.polygons[idx[2]].area)) self.assertEqual(900, int(results.polygons[idx[3]].area)) self.assertEqual(2500, int(results.polygons[idx[4]].area)) self.assertEqual(85, results.labels[idx[0]]) self.assertEqual(255, results.labels[idx[1]]) self.assertEqual(190, results.labels[idx[2]]) self.assertEqual(85, results.labels[idx[3]]) self.assertEqual(190, results.labels[idx[4]])
def main(argv): with CytomineJob.from_cli(argv) as cj: # use only images from the current project cj.job.update(progress=1, statusComment="Preparing execution") # extract images to process if cj.parameters.cytomine_zoom_level > 0 and ( cj.parameters.cytomine_tile_size != 256 or cj.parameters.cytomine_tile_overlap != 0): raise ValueError( "when using zoom_level > 0, tile size should be 256 " "(given {}) and overlap should be 0 (given {})".format( cj.parameters.cytomine_tile_size, cj.parameters.cytomine_tile_overlap)) cj.job.update( progress=1, statusComment="Preparing execution (creating folders,...).") # working path root_path = str(Path.home()) working_path = os.path.join(root_path, "images") os.makedirs(working_path, exist_ok=True) # load training information cj.job.update(progress=5, statusComment="Extract properties from training job.") train_job = Job().fetch(cj.parameters.cytomine_id_job) properties = PropertyCollection(train_job).fetch().as_dict() binary = str2bool(properties["binary"].value) classes = parse_domain_list(properties["classes"].value) cj.job.update(progress=10, statusComment="Download the model file.") attached_files = AttachedFileCollection(train_job).fetch() model_file = attached_files.find_by_attribute("filename", "model.joblib") model_filepath = os.path.join(root_path, "model.joblib") model_file.download(model_filepath, override=True) pyxit = joblib.load(model_filepath) # set n_jobs pyxit.base_estimator.n_jobs = cj.parameters.n_jobs pyxit.n_jobs = cj.parameters.n_jobs cj.job.update(progress=45, statusComment="Build workflow.") builder = SSLWorkflowBuilder() builder.set_tile_size(cj.parameters.cytomine_tile_size, cj.parameters.cytomine_tile_size) builder.set_overlap(cj.parameters.cytomine_tile_overlap) builder.set_tile_builder( CytomineTileBuilder(working_path, n_jobs=cj.parameters.n_jobs)) builder.set_logger(StandardOutputLogger(level=Logger.INFO)) builder.set_n_jobs(1) builder.set_background_class(0) # value 0 will prevent merging but still requires to run the merging check # procedure (inefficient) builder.set_distance_tolerance(2 if cj.parameters.union_enabled else 0) builder.set_segmenter( ExtraTreesSegmenter( pyxit=pyxit, classes=classes, prediction_step=cj.parameters.pyxit_prediction_step, background=0, min_std=cj.parameters.tile_filter_min_stddev, max_mean=cj.parameters.tile_filter_max_mean)) workflow = builder.get() area_checker = AnnotationAreaChecker( min_area=cj.parameters.min_annotation_area, max_area=cj.parameters.max_annotation_area) def get_term(label): if binary: if "cytomine_id_predict_term" not in cj.parameters: return [] else: return [int(cj.parameters.cytomine_id_predict_term)] # multi-class return [label] zones = extract_images_or_rois(cj.parameters) for zone in cj.monitor(zones, start=50, end=90, period=0.05, prefix="Segmenting images/ROIs"): results = workflow.process(zone) annotations = AnnotationCollection() for obj in results: if not area_checker.check(obj.polygon): continue polygon = obj.polygon if isinstance(zone, ImageWindow): polygon = affine_transform( polygon, [1, 0, 0, 1, zone.abs_offset_x, zone.abs_offset_y]) polygon = change_referential(polygon, zone.base_image.height) if cj.parameters.cytomine_zoom_level > 0: zoom_mult = (2**cj.parameters.cytomine_zoom_level) polygon = affine_transform( polygon, [zoom_mult, 0, 0, zoom_mult, 0, 0]) annotations.append( Annotation(location=polygon.wkt, id_terms=get_term(obj.label), id_project=cj.project.id, id_image=zone.base_image.image_instance.id)) annotations.save() cj.job.update(status=Job.TERMINATED, status_comment="Finish", progress=100)
def main(argv): with CytomineJob.from_cli(argv) as job: model_path = os.path.join(str(Path.home()), "models", "thyroid-unet") model_filepath = pick_model(model_path, job.parameters.tile_size, job.parameters.cytomine_zoom_level) device = torch.device(job.parameters.device) unet = Unet(job.parameters.init_fmaps, n_classes=1) unet.load_state_dict(torch.load(model_filepath, map_location=device)) unet.to(device) unet.eval() segmenter = UNetSegmenter(device=job.parameters.device, unet=unet, classes=[0, 1], threshold=job.parameters.threshold) working_path = os.path.join(str(Path.home()), "tmp") tile_builder = CytomineTileBuilder(working_path) builder = SSLWorkflowBuilder() builder.set_n_jobs(1) builder.set_overlap(job.parameters.tile_overlap) builder.set_tile_size(job.parameters.tile_size, job.parameters.tile_size) builder.set_tile_builder(tile_builder) builder.set_border_tiles(Workflow.BORDER_TILES_EXTEND) builder.set_background_class(0) builder.set_distance_tolerance(1) builder.set_seg_batch_size(job.parameters.batch_size) builder.set_segmenter(segmenter) workflow = builder.get() slide = CytomineSlide(img_instance=ImageInstance().fetch( job.parameters.cytomine_id_image), zoom_level=job.parameters.cytomine_zoom_level) results = workflow.process(slide) print("-------------------------") print(len(results)) print("-------------------------") collection = AnnotationCollection() for obj in results: wkt = shift_poly(obj.polygon, slide, zoom_level=job.parameters.cytomine_zoom_level).wkt collection.append( Annotation(location=wkt, id_image=job.parameters.cytomine_id_image, id_terms=[154005477], id_project=job.project.id)) collection.save(n_workers=job.parameters.n_jobs) return {}
def testSSLWorkflowBuilder(self): segmenter = DumbSegmenter() builder = SSLWorkflowBuilder() builder.set_n_jobs(5) builder.set_tile_size(512, 768) builder.set_overlap(3) builder.set_distance_tolerance(7) builder.set_background_class(5) builder.set_logger(StandardOutputLogger(Logger.DEBUG)) with self.assertRaises(MissingComponentException): builder.get() builder.set_segmenter(segmenter) builder.set_default_tile_builder() workflow = builder.get() self.assertIsInstance(workflow, SSLWorkflow) self.assertEqual(workflow._n_jobs, 5) self.assertEqual(workflow._tile_overlap, 3) self.assertEqual(workflow._tile_max_height, 512) self.assertEqual(workflow._tile_max_width, 768) self.assertIsInstance(workflow._tile_builder, DefaultTileBuilder) self.assertIsInstance(workflow.logger, StandardOutputLogger) self.assertEqual(workflow._locator._background, 5)