Example #1
0
    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]])
Example #2
0
    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)
Example #3
0
    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]])
Example #4
0
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)
Example #5
0
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 {}
Example #6
0
    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)