示例#1
0
    def testNoObjects(self):
        """Test detection on empty image"""
        w, h = 200, 200
        image = np.zeros((h, w), dtype="uint8")

        builder = SLDCWorkflowBuilder()
        builder.set_segmenter(CustomSegmenter())
        builder.add_classifier(CircleRule(),
                               ColorClassifier(),
                               dispatching_label="circle")
        builder.add_classifier(SquareRule(), ColorClassifier())
        workflow = builder.get()

        # Execute
        results = workflow.process(NumpyImage(image))

        self.assertEqual(len(results), 0)
示例#2
0
文件: test_sldc.py 项目: waliens/sldc
    def testDetectCircleParallel(self):
        """A test which executes a full workflow on image containing a white circle in the center of an black image in
        parallel
        """
        # generate circle image
        w, h = 2000, 2000
        image = np.zeros((w, h, 3), dtype="uint8")
        image = draw_circle(image, 750, (1000, 1000), [129, 129, 129])

        # build workflow
        builder = SLDCWorkflowBuilder()
        builder.set_n_jobs(2)
        builder.set_segmenter(CircleSegmenter())
        builder.add_catchall_classifier(CircleClassifier())
        builder.set_parallel_dc(True)
        workflow = builder.get()

        # process image
        workflow_info = workflow.process(NumpyImage(image))

        # Check results
        self.assertEqual(len(workflow_info.polygons), 1)

        # Check circle
        polygon = workflow_info.polygons[0]
        self.assertEqual(relative_error(polygon.area, np.pi * 750 * 750) <= 0.005, True)
        self.assertEqual(relative_error(polygon.centroid.x, 1000) <= 0.005, True)
        self.assertEqual(relative_error(polygon.centroid.y, 1000) <= 0.005, True)
        assert_array_equal(workflow_info.labels, [1])
        assert_array_almost_equal(workflow_info.probas, [1.0])
        assert_array_equal(workflow_info.dispatches, ["catchall"])

        # check other information
        timing = workflow_info.timing
        self.assertEqual(timing.get_phases_hierarchy(), {"workflow.sldc": {
            "detect": {"load": None, "segment": None, "locate": None},
            "merge": None,
            "dispatch_classify": {"dispatch": None, "classify": None}
        }})
示例#3
0
文件: test_sldc.py 项目: waliens/sldc
    def testNoObjects(self):
        """Test detection on empty image"""
        w, h = 200, 200
        image = np.zeros((h, w), dtype="uint8")

        builder = SLDCWorkflowBuilder()
        builder.set_segmenter(CustomSegmenter())
        builder.add_classifier(CircleRule(), ColorClassifier(), dispatching_label="circle")
        builder.add_classifier(SquareRule(), ColorClassifier())
        workflow = builder.get()

        # Execute
        results = workflow.process(NumpyImage(image))

        self.assertEqual(len(results), 0)
示例#4
0
    def testDetectCircle(self):
        """A test which executes a full workflow on image containing a white circle in the center of an black image
        """
        # generate circle image
        w, h = 2000, 2000
        image = np.zeros((w, h, 3), dtype="uint8")
        image = draw_circle(image, 750, (1000, 1000), color=[129, 129, 129])

        # build workflow
        builder = SLDCWorkflowBuilder()
        builder.set_segmenter(CircleSegmenter())
        builder.add_catchall_classifier(CircleClassifier())
        workflow = builder.get()

        # process image
        workflow_info = workflow.process(NumpyImage(image))

        # Check results
        self.assertEqual(len(workflow_info.polygons), 1)

        # Check circle
        polygon = workflow_info.polygons[0]
        self.assertEqual(
            relative_error(polygon.area, np.pi * 750 * 750) <= 0.005, True)
        self.assertEqual(
            relative_error(polygon.centroid.x, 1000) <= 0.005, True)
        self.assertEqual(
            relative_error(polygon.centroid.y, 1000) <= 0.005, True)
        assert_array_equal(workflow_info.labels, [1])
        assert_array_almost_equal(workflow_info.probas, [1.0])
        assert_array_equal(workflow_info.dispatches, ["catchall"])

        # check other information
        timing = workflow_info.timing
        self.assertEqual(
            timing.get_phases_hierarchy(), {
                "workflow.sldc": {
                    "detect": {
                        "load": None,
                        "segment": None,
                        "locate": None
                    },
                    "merge": None,
                    "dispatch_classify": {
                        "dispatch": None,
                        "classify": None
                    }
                }
            })
示例#5
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)
示例#6
0
文件: test_sldc.py 项目: waliens/sldc
    def testWorkflowWithExcludedObjects(self):
        # generate circle image
        w, h = 300, 100
        image = np.zeros((h, w,), dtype="uint8")
        image = draw_circle(image, 25, (100, 40), 255)  # pi * 25 * 25 -> ~ 1963
        image = draw_circle(image, 35, (200, 60), 255)  # pi * 35 * 35 -> ~ 3858

        # build the workflow
        builder = SLDCWorkflowBuilder()
        builder.set_segmenter(CustomSegmenter())
        builder.add_classifier(MinAreaRule(2000), ColorClassifier(), "big")
        workflow = builder.get()

        # execute
        results = workflow.process(NumpyImage(image))

        # validate number of results
        count = len(results)
        self.assertEqual(count, 2)

        # sort polygons
        sorted_idx = sorted(range(count), key=lambda i: (results.polygons[i].centroid.y, results.polygons[i].centroid.x))

        # first shape (excluded)
        shape1 = results.polygons[sorted_idx[0]]
        self.assertLess(relative_error(shape1.area, np.pi * 25 * 25), 0.025)
        self.assertLess(relative_error(shape1.centroid.x, 100), 0.025)
        self.assertLess(relative_error(shape1.centroid.y, 40), 0.025)
        self.assertEqual(results.dispatches[sorted_idx[0]], None)
        self.assertEqual(results.labels[sorted_idx[0]], None)
        self.assertAlmostEqual(results.probas[sorted_idx[0]], 0.0)

        # second shape (include)
        shape2 = results.polygons[sorted_idx[1]]
        self.assertLess(relative_error(shape2.area, np.pi * 35 * 35), 0.025)
        self.assertLess(relative_error(shape2.centroid.x, 200), 0.025)
        self.assertLess(relative_error(shape2.centroid.y, 60), 0.025)
        self.assertEqual(results.dispatches[sorted_idx[1]], "big")
        self.assertEqual(results.labels[sorted_idx[1]], ColorClassifier.WHITE)
        self.assertAlmostEqual(results.probas[sorted_idx[1]], 1.0)

        # check other information
        timing = results.timing
        self.assertEqual(timing.get_phases_hierarchy(), {"workflow.sldc": {
            "detect": {"load": None, "segment": None, "locate": None},
            "merge": None,
            "dispatch_classify": {"dispatch": None, "classify": None}
        }})
示例#7
0
    def testSquareIncluded(self):
        # generate the image to be processed
        w, h = 2000, 2000
        image = np.zeros((h, w), dtype=np.uint8)

        # locations of the 9 multi-squares
        positions = [(w // 7, h // 7), (3 * w // 7, h // 7),
                     (5 * w // 7, h // 7), (w // 7, 3 * h // 7),
                     (3 * w // 7, 3 * h // 7), (5 * w // 7, 3 * h // 7),
                     (w // 7, 5 * h // 7), (3 * w // 7, 5 * h // 7),
                     (5 * w // 7, 5 * h // 7)]

        for position in positions:
            image = draw_multisquare(image, position, w // 7, color_in=127)

        # Build workflow
        builder = SLDCWorkflowBuilder()

        # Build workflow 1
        builder.set_segmenter(BigShapeSegmenter())
        builder.add_catchall_classifier(DumbClassifier())
        builder.set_tile_size(512, 512)
        workflow1 = builder.get()

        # Build workflow 2
        builder.set_segmenter(SmallSquareSegmenter())
        builder.add_catchall_classifier(DumbClassifier())
        workflow2 = builder.get()

        # Build chaining
        chain_builder = WorkflowChainBuilder()
        chain_builder.set_first_workflow(workflow1, label="big_squares")
        chain_builder.add_executor(workflow2, label="small_squares")
        chain = chain_builder.get()

        # Launch
        chain_info = chain.process(NumpyImage(image))

        # check results
        big_area = (w // 7)**2
        small_area = (w / 35)**2

        info1 = chain_info["big_squares"]
        self.assertEqual(9, len(info1))
        for object_info in info1:
            self.assertTrue(
                relative_error(object_info.polygon.area, big_area) < 0.005)
            self.assertEqual("catchall", object_info.dispatch)
            self.assertEqual(1, object_info.label)
            self.assertAlmostEqual(1.0, object_info.proba)

        info2 = chain_info["small_squares"]
        self.assertEqual(36, len(info2))
        for object_info in info2:
            self.assertTrue(
                relative_error(object_info.polygon.area, small_area) < 0.005)
            self.assertEqual("catchall", object_info.dispatch)
            self.assertEqual(1, object_info.label)
            self.assertAlmostEqual(1.0, object_info.proba)
示例#8
0
    def testSquareAndCircleIncluded(self):
        w, h = 2000, 2000
        image = np.zeros((h, w), dtype=np.uint8)
        # locations of the 9 multi-squares
        shapes = [("c", (w // 7, h // 7)), ("s", (3 * w // 7, h // 7)),
                  ("s", (5 * w // 7, h // 7)), ("s", (w // 7, 3 * h // 7)),
                  ("c", (3 * w // 7, 3 * h // 7)),
                  ("s", (5 * w // 7, 3 * h // 7)), ("c", (w // 7, 5 * h // 7)),
                  ("s", (3 * w // 7, 5 * h // 7)),
                  ("c", (5 * w // 7, 5 * h // 7))]

        for shape, position in shapes:
            if shape == "c":
                image = draw_multicircle(image, position, w // 7, color_in=87)
            elif shape == "s":
                image = draw_multisquare(image, position, w // 7, color_in=187)

        # Build workflows
        # 1st: find big shapes and dispatch them as circle or square
        # 2nd: find small circles in found circle shapes
        # 3rd: find small squares in found square shape
        builder = SLDCWorkflowBuilder()

        builder.set_segmenter(BigShapeSegmenter())
        builder.add_classifier(CircleDispatch(),
                               DumbClassifier(),
                               dispatching_label="circle")
        builder.add_classifier(SquareDispatch(),
                               DumbClassifier(),
                               dispatching_label="square")
        builder.set_tile_size(512, 512)
        workflow1 = builder.get()

        builder.set_segmenter(SmallCircleSegmenter())
        builder.add_catchall_classifier(DumbClassifier())
        workflow2 = builder.get()

        builder.set_segmenter(SmallSquareSegmenter())
        builder.add_catchall_classifier(DumbClassifier())
        workflow3 = builder.get()

        # Build chain
        chain_builder = WorkflowChainBuilder()
        chain_builder.set_first_workflow(workflow1)
        chain_builder.add_executor(workflow2, filter=CircleShapeFilter())
        chain_builder.add_executor(workflow3,
                                   filter=SquareShapeFilter(),
                                   n_jobs=2)
        chain = chain_builder.get()

        chain_info = chain.process(NumpyImage(image))

        info1 = chain_info[0]
        self.assertEqual(9, len(info1))
        self.assertEqual(4,
                         len([d for d in info1.dispatches if d == "circle"]))
        self.assertEqual(5,
                         len([d for d in info1.dispatches if d == "square"]))

        info2 = chain_info[1]
        self.assertEqual(16, len(info2))

        info3 = chain_info[2]
        self.assertEqual(20, len(info3))
示例#9
0
    def testWorkflowWithCustomDispatcher(self):
        # generate circle image
        w, h = 1000, 1000
        image = np.zeros((
            w,
            h,
        ), dtype="uint8")
        image = draw_circle(image, 10, (125, 125),
                            255)  # pi * 10 * 10 -> ~ 314
        image = draw_circle(image, 25, (250, 750),
                            255)  # pi * 25 * 25 -> ~ 1963
        image = draw_square(image, 26, (250, 250), 255)  # 26 * 26 -> 676
        image = draw_square(image, 50, (750, 750), 127)  # 50 * 50 -> 2500

        # build the workflow
        builder = SLDCWorkflowBuilder()
        builder.set_segmenter(CustomSegmenter())
        builder.set_one_shot_dispatcher(CustomDispatcher(1000), {
            "BIG": ColorClassifier(),
            "SMALL": ColorClassifier()
        })
        workflow = builder.get()

        # execute
        results = workflow.process(NumpyImage(image))

        # validate number of results
        count = len(results)
        self.assertEqual(count, 4)

        # sort polygons
        sorted_idx = sorted(
            range(count),
            key=lambda i:
            (results.polygons[i].centroid.y, results.polygons[i].centroid.x))

        # first circle
        circle1 = results.polygons[sorted_idx[0]]
        self.assertTrue(relative_error(circle1.area, np.pi * 10 * 10) < 0.025)
        self.assertTrue(relative_error(circle1.centroid.x, 125) < 0.025)
        self.assertTrue(relative_error(circle1.centroid.y, 125) < 0.025)
        self.assertEqual(results.dispatches[sorted_idx[0]], "SMALL")
        self.assertEqual(results.labels[sorted_idx[0]], ColorClassifier.WHITE)
        self.assertAlmostEqual(results.probas[sorted_idx[0]], 1.0)

        # first square
        square1 = results.polygons[sorted_idx[1]]
        self.assertTrue(relative_error(square1.area, 26 * 26) < 0.025)
        self.assertTrue(relative_error(square1.centroid.x, 250) < 0.025)
        self.assertTrue(relative_error(square1.centroid.y, 250) < 0.025)
        self.assertEqual(results.dispatches[sorted_idx[1]], "SMALL")
        self.assertEqual(results.labels[sorted_idx[1]], ColorClassifier.WHITE)
        self.assertAlmostEqual(results.probas[sorted_idx[1]], 1.0)

        # second circle
        circle2 = results.polygons[sorted_idx[2]]
        self.assertTrue(relative_error(circle2.area, np.pi * 25 * 25) < 0.025)
        self.assertTrue(relative_error(circle2.centroid.x, 250) < 0.025)
        self.assertTrue(relative_error(circle2.centroid.y, 750) < 0.025)
        self.assertEqual(results.dispatches[sorted_idx[2]], "BIG")
        self.assertEqual(results.labels[sorted_idx[2]], ColorClassifier.WHITE)
        self.assertAlmostEqual(results.probas[sorted_idx[2]], 1.0)

        # second square
        square2 = results.polygons[sorted_idx[3]]
        self.assertTrue(relative_error(square2.area, 50 * 50) < 0.025)
        self.assertTrue(relative_error(square2.centroid.x, 750) < 0.025)
        self.assertTrue(relative_error(square2.centroid.y, 750) < 0.025)
        self.assertEqual(results.dispatches[sorted_idx[3]], "BIG")
        self.assertEqual(results.labels[sorted_idx[3]], ColorClassifier.GREY)
        self.assertAlmostEqual(results.probas[sorted_idx[3]], 1.0)

        # check other information
        timing = results.timing
        self.assertEqual(
            timing.get_phases_hierarchy(), {
                "workflow.sldc": {
                    "detect": {
                        "load": None,
                        "segment": None,
                        "locate": None
                    },
                    "merge": None,
                    "dispatch_classify": {
                        "dispatch": None,
                        "classify": None
                    }
                }
            })
示例#10
0
    def testWorkflowWithExcludedObjects(self):
        # generate circle image
        w, h = 300, 100
        image = np.zeros((
            h,
            w,
        ), dtype="uint8")
        image = draw_circle(image, 25, (100, 40),
                            255)  # pi * 25 * 25 -> ~ 1963
        image = draw_circle(image, 35, (200, 60),
                            255)  # pi * 35 * 35 -> ~ 3858

        # build the workflow
        builder = SLDCWorkflowBuilder()
        builder.set_segmenter(CustomSegmenter())
        builder.add_classifier(MinAreaRule(2000), ColorClassifier(), "big")
        workflow = builder.get()

        # execute
        results = workflow.process(NumpyImage(image))

        # validate number of results
        count = len(results)
        self.assertEqual(count, 2)

        # sort polygons
        sorted_idx = sorted(
            range(count),
            key=lambda i:
            (results.polygons[i].centroid.y, results.polygons[i].centroid.x))

        # first shape (excluded)
        shape1 = results.polygons[sorted_idx[0]]
        self.assertLess(relative_error(shape1.area, np.pi * 25 * 25), 0.025)
        self.assertLess(relative_error(shape1.centroid.x, 100), 0.025)
        self.assertLess(relative_error(shape1.centroid.y, 40), 0.025)
        self.assertEqual(results.dispatches[sorted_idx[0]], None)
        self.assertEqual(results.labels[sorted_idx[0]], None)
        self.assertAlmostEqual(results.probas[sorted_idx[0]], 0.0)

        # second shape (include)
        shape2 = results.polygons[sorted_idx[1]]
        self.assertLess(relative_error(shape2.area, np.pi * 35 * 35), 0.025)
        self.assertLess(relative_error(shape2.centroid.x, 200), 0.025)
        self.assertLess(relative_error(shape2.centroid.y, 60), 0.025)
        self.assertEqual(results.dispatches[sorted_idx[1]], "big")
        self.assertEqual(results.labels[sorted_idx[1]], ColorClassifier.WHITE)
        self.assertAlmostEqual(results.probas[sorted_idx[1]], 1.0)

        # check other information
        timing = results.timing
        self.assertEqual(
            timing.get_phases_hierarchy(), {
                "workflow.sldc": {
                    "detect": {
                        "load": None,
                        "segment": None,
                        "locate": None
                    },
                    "merge": None,
                    "dispatch_classify": {
                        "dispatch": None,
                        "classify": None
                    }
                }
            })
示例#11
0
    def testFindCircleAndSquare(self):
        """Test the workflow on an image containing both squares and circles of different colors
        Two squares of side: 200
            - white centered in (1000, 1000)
            - grey centered in (3000, 3000)
        Two circles of side: 100
            - white centered in (1000, 3000)
            - grey centered in (3000, 1000)
        Another white square of side 300 centered in (2000,2000)
        """
        # square
        w, h = 2000, 2000
        image = np.zeros((
            w,
            h,
        ), dtype="uint8")
        image = draw_circle(image, 100, (500, 1500), 255)
        image = draw_circle(image, 100, (1500, 600), 127)
        image = draw_square(image, 200, (500, 500), 255)
        image = draw_square(image, 200, (1500, 1500), 127)
        image = draw_square(image, 300, (1000, 1000), 255)

        # Build the workflow
        builder = SLDCWorkflowBuilder()
        builder.set_segmenter(CustomSegmenter())
        builder.add_classifier(CircleRule(),
                               ColorClassifier(),
                               dispatching_label="circle")
        builder.add_classifier(SquareRule(), ColorClassifier())
        workflow = builder.get()

        # Execute
        results = workflow.process(NumpyImage(image))

        # count check
        count = len(results)
        self.assertEqual(count, 5)

        # sort polygons
        sorted_idx = sorted(
            range(count),
            key=lambda i:
            (results.polygons[i].centroid.y, results.polygons[i].centroid.x))

        # first square
        square1 = results.polygons[sorted_idx[0]]
        self.assertEqual(relative_error(square1.area, 200 * 200) < 0.005, True)
        self.assertEqual(relative_error(square1.centroid.x, 500) < 0.005, True)
        self.assertEqual(relative_error(square1.centroid.y, 500) < 0.005, True)
        self.assertEqual(results.dispatches[sorted_idx[0]], "1")  # square
        self.assertEqual(results.labels[sorted_idx[0]],
                         ColorClassifier.WHITE)  # white
        self.assertAlmostEqual(results.probas[sorted_idx[0]], 1.0)

        # first circle
        circle1 = results.polygons[sorted_idx[1]]
        self.assertEqual(
            relative_error(circle1.area, np.pi * 100 * 100) < 0.005, True)
        self.assertEqual(
            relative_error(circle1.centroid.x, 1500) < 0.005, True)
        self.assertEqual(relative_error(circle1.centroid.y, 600) < 0.005, True)
        self.assertEqual(results.dispatches[sorted_idx[1]], "circle")  # circle
        self.assertEqual(results.labels[sorted_idx[1]],
                         ColorClassifier.GREY)  # grey
        self.assertAlmostEqual(results.probas[sorted_idx[1]], 1.0)

        # second square (centered)
        square2 = results.polygons[sorted_idx[2]]
        self.assertEqual(relative_error(square2.area, 300 * 300) < 0.005, True)
        self.assertEqual(
            relative_error(square2.centroid.x, 1000) < 0.005, True)
        self.assertEqual(
            relative_error(square2.centroid.y, 1000) < 0.005, True)
        self.assertEqual(results.dispatches[sorted_idx[2]], "1")  # square
        self.assertEqual(results.labels[sorted_idx[2]],
                         ColorClassifier.WHITE)  # white
        self.assertAlmostEqual(results.probas[sorted_idx[2]], 1.0)

        # second circle
        circle2 = results.polygons[sorted_idx[3]]
        self.assertEqual(
            relative_error(circle2.area, np.pi * 100 * 100) < 0.005, True)
        self.assertEqual(relative_error(circle2.centroid.x, 500) < 0.005, True)
        self.assertEqual(
            relative_error(circle2.centroid.y, 1500) < 0.005, True)
        self.assertEqual(results.dispatches[sorted_idx[3]], "circle")  # circle
        self.assertEqual(results.labels[sorted_idx[3]],
                         ColorClassifier.WHITE)  # grey
        self.assertAlmostEqual(results.probas[sorted_idx[3]], 1.0)

        # third square
        square3 = results.polygons[sorted_idx[4]]
        self.assertEqual(relative_error(square3.area, 200 * 200) < 0.005, True)
        self.assertEqual(
            relative_error(square3.centroid.x, 1500) < 0.005, True)
        self.assertEqual(
            relative_error(square3.centroid.y, 1500) < 0.005, True)
        self.assertEqual(results.dispatches[sorted_idx[4]], "1")  # square
        self.assertEqual(results.labels[sorted_idx[4]],
                         ColorClassifier.GREY)  # white
        self.assertAlmostEqual(results.probas[sorted_idx[4]], 1.0)

        # check other information
        timing = results.timing
        self.assertEqual(
            timing.get_phases_hierarchy(), {
                "workflow.sldc": {
                    "detect": {
                        "load": None,
                        "segment": None,
                        "locate": None
                    },
                    "merge": None,
                    "dispatch_classify": {
                        "dispatch": None,
                        "classify": None
                    }
                }
            })
示例#12
0
文件: test_sldc.py 项目: waliens/sldc
    def testFindCircleAndSquare(self):
        """Test the workflow on an image containing both squares and circles of different colors
        Two squares of side: 200
            - white centered in (1000, 1000)
            - grey centered in (3000, 3000)
        Two circles of side: 100
            - white centered in (1000, 3000)
            - grey centered in (3000, 1000)
        Another white square of side 300 centered in (2000,2000)
        """
        # square
        w, h = 2000, 2000
        image = np.zeros((w, h,), dtype="uint8")
        image = draw_circle(image, 100, (500, 1500), 255)
        image = draw_circle(image, 100, (1500, 600), 127)
        image = draw_square(image, 200, (500, 500), 255)
        image = draw_square(image, 200, (1500, 1500), 127)
        image = draw_square(image, 300, (1000, 1000), 255)

        # Build the workflow
        builder = SLDCWorkflowBuilder()
        builder.set_segmenter(CustomSegmenter())
        builder.add_classifier(CircleRule(), ColorClassifier(), dispatching_label="circle")
        builder.add_classifier(SquareRule(), ColorClassifier())
        workflow = builder.get()

        # Execute
        results = workflow.process(NumpyImage(image))

        # count check
        count = len(results)
        self.assertEqual(count, 5)

        # sort polygons
        sorted_idx = sorted(range(count), key=lambda i: (results.polygons[i].centroid.y, results.polygons[i].centroid.x))

        # first square
        square1 = results.polygons[sorted_idx[0]]
        self.assertEqual(relative_error(square1.area, 200 * 200) < 0.005, True)
        self.assertEqual(relative_error(square1.centroid.x, 500) < 0.005, True)
        self.assertEqual(relative_error(square1.centroid.y, 500) < 0.005, True)
        self.assertEqual(results.dispatches[sorted_idx[0]], "1")  # square
        self.assertEqual(results.labels[sorted_idx[0]], ColorClassifier.WHITE)  # white
        self.assertAlmostEqual(results.probas[sorted_idx[0]], 1.0)

        # first circle
        circle1 = results.polygons[sorted_idx[1]]
        self.assertEqual(relative_error(circle1.area, np.pi * 100 * 100) < 0.005, True)
        self.assertEqual(relative_error(circle1.centroid.x, 1500) < 0.005, True)
        self.assertEqual(relative_error(circle1.centroid.y, 600) < 0.005, True)
        self.assertEqual(results.dispatches[sorted_idx[1]], "circle")  # circle
        self.assertEqual(results.labels[sorted_idx[1]], ColorClassifier.GREY)  # grey
        self.assertAlmostEqual(results.probas[sorted_idx[1]], 1.0)

        # second square (centered)
        square2 = results.polygons[sorted_idx[2]]
        self.assertEqual(relative_error(square2.area, 300 * 300) < 0.005, True)
        self.assertEqual(relative_error(square2.centroid.x, 1000) < 0.005, True)
        self.assertEqual(relative_error(square2.centroid.y, 1000) < 0.005, True)
        self.assertEqual(results.dispatches[sorted_idx[2]], "1")  # square
        self.assertEqual(results.labels[sorted_idx[2]], ColorClassifier.WHITE)  # white
        self.assertAlmostEqual(results.probas[sorted_idx[2]], 1.0)

        # second circle
        circle2 = results.polygons[sorted_idx[3]]
        self.assertEqual(relative_error(circle2.area, np.pi * 100 * 100) < 0.005, True)
        self.assertEqual(relative_error(circle2.centroid.x, 500) < 0.005, True)
        self.assertEqual(relative_error(circle2.centroid.y, 1500) < 0.005, True)
        self.assertEqual(results.dispatches[sorted_idx[3]], "circle")  # circle
        self.assertEqual(results.labels[sorted_idx[3]], ColorClassifier.WHITE)  # grey
        self.assertAlmostEqual(results.probas[sorted_idx[3]], 1.0)

        # third square
        square3 = results.polygons[sorted_idx[4]]
        self.assertEqual(relative_error(square3.area, 200 * 200) < 0.005, True)
        self.assertEqual(relative_error(square3.centroid.x, 1500) < 0.005, True)
        self.assertEqual(relative_error(square3.centroid.y, 1500) < 0.005, True)
        self.assertEqual(results.dispatches[sorted_idx[4]], "1")  # square
        self.assertEqual(results.labels[sorted_idx[4]], ColorClassifier.GREY)  # white
        self.assertAlmostEqual(results.probas[sorted_idx[4]], 1.0)

        # check other information
        timing = results.timing
        self.assertEqual(timing.get_phases_hierarchy(), {"workflow.sldc": {
            "detect": {"load": None, "segment": None, "locate": None},
            "merge": None,
            "dispatch_classify": {"dispatch": None, "classify": None}
        }})
示例#13
0
    def testSLDCWorkflowWithOneShotDispatcher(self):
        # pre build components
        segmenter = DumbSegmenter()
        dispatcher = DumbDispatcher()
        classifier = DumbClassifier()
        rule = DumbRule()
        logger = StandardOutputLogger(Logger.DEBUG)

        builder = SLDCWorkflowBuilder()
        builder.set_tile_size(512, 768)
        builder.set_overlap(3)
        builder.set_distance_tolerance(5)
        builder.set_n_jobs(5)
        builder.set_logger(logger)
        builder.set_parallel_dc(True)
        builder.set_tile_builder(None)

        with self.assertRaises(MissingComponentException):
            builder.get()

        builder.set_segmenter(segmenter)

        with self.assertRaises(MissingComponentException):
            builder.get()

        builder.set_default_tile_builder()

        with self.assertRaises(MissingComponentException):
            builder.get()

        builder.set_one_shot_dispatcher(dispatcher, {"default": classifier})

        with self.assertRaises(InvalidBuildingException):
            builder.add_classifier(rule, classifier, dispatching_label="default")

        with self.assertRaises(InvalidBuildingException):
            builder.add_catchall_classifier(classifier, dispatching_label="default")

        workflow = builder.get()
        self.assertIsInstance(workflow, SLDCWorkflow)
        self.assertEqual(workflow._segmenter, segmenter)
        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.assertEqual(workflow.logger, logger)
        self.assertIsInstance(workflow._tile_builder, DefaultTileBuilder)
        self.assertEqual(workflow._dispatch_classifier._dispatcher, dispatcher)
        self.assertEqual(len(workflow._dispatch_classifier._classifiers), 1)
        self.assertEqual(workflow._dispatch_classifier._classifiers[0], classifier)
示例#14
0
    def testSLDCWorkflowWithRuleDispatcher(self):
        # pre build components
        segmenter = DumbSegmenter()
        tile_builder = DefaultTileBuilder()
        dispatcher = DumbDispatcher()
        classifier1 = DumbClassifier()
        classifier2 = DumbClassifier()
        rule1 = DumbRule()
        rule2 = DumbRule()

        builder = SLDCWorkflowBuilder()
        builder.set_segmenter(segmenter)
        builder.set_tile_builder(tile_builder)
        builder.add_classifier(rule1, classifier1)
        builder.add_classifier(rule2, classifier2)

        with self.assertRaises(InvalidBuildingException):
            builder.set_one_shot_dispatcher(dispatcher, {"default": classifier1})

        workflow = builder.get()
        self.assertIsInstance(workflow, SLDCWorkflow)
        self.assertEqual(len(workflow._dispatch_classifier._classifiers), 2)
        self.assertEqual(workflow._dispatch_classifier._classifiers[0], classifier1)
        self.assertEqual(workflow._dispatch_classifier._classifiers[1], classifier2)
        self.assertIsInstance(workflow._dispatch_classifier._dispatcher, RuleBasedDispatcher)
        self.assertEqual(len(workflow._dispatch_classifier._dispatcher._rules), 2)
        self.assertEqual(workflow._dispatch_classifier._dispatcher._rules[0], rule1)
        self.assertEqual(workflow._dispatch_classifier._dispatcher._rules[1], rule2)
示例#15
0
文件: test_sldc.py 项目: waliens/sldc
    def testWorkflowWithCustomDispatcher(self):
        # generate circle image
        w, h = 1000, 1000
        image = np.zeros((w, h,), dtype="uint8")
        image = draw_circle(image, 10, (125, 125), 255)  # pi * 10 * 10 -> ~ 314
        image = draw_circle(image, 25, (250, 750), 255)  # pi * 25 * 25 -> ~ 1963
        image = draw_square(image, 26, (250, 250), 255)  # 26 * 26 -> 676
        image = draw_square(image, 50, (750, 750), 127)  # 50 * 50 -> 2500

        # build the workflow
        builder = SLDCWorkflowBuilder()
        builder.set_segmenter(CustomSegmenter())
        builder.set_one_shot_dispatcher(CustomDispatcher(1000), {
            "BIG": ColorClassifier(),
            "SMALL": ColorClassifier()
        })
        workflow = builder.get()

        # execute
        results = workflow.process(NumpyImage(image))

        # validate number of results
        count = len(results)
        self.assertEqual(count, 4)

        # sort polygons
        sorted_idx = sorted(range(count), key=lambda i: (results.polygons[i].centroid.y, results.polygons[i].centroid.x))

        # first circle
        circle1 = results.polygons[sorted_idx[0]]
        self.assertTrue(relative_error(circle1.area, np.pi * 10 * 10) < 0.025)
        self.assertTrue(relative_error(circle1.centroid.x, 125) < 0.025)
        self.assertTrue(relative_error(circle1.centroid.y, 125) < 0.025)
        self.assertEqual(results.dispatches[sorted_idx[0]], "SMALL")
        self.assertEqual(results.labels[sorted_idx[0]], ColorClassifier.WHITE)
        self.assertAlmostEqual(results.probas[sorted_idx[0]], 1.0)

        # first square
        square1 = results.polygons[sorted_idx[1]]
        self.assertTrue(relative_error(square1.area, 26 * 26) < 0.025)
        self.assertTrue(relative_error(square1.centroid.x, 250) < 0.025)
        self.assertTrue(relative_error(square1.centroid.y, 250) < 0.025)
        self.assertEqual(results.dispatches[sorted_idx[1]], "SMALL")
        self.assertEqual(results.labels[sorted_idx[1]], ColorClassifier.WHITE)
        self.assertAlmostEqual(results.probas[sorted_idx[1]], 1.0)

        # second circle
        circle2 = results.polygons[sorted_idx[2]]
        self.assertTrue(relative_error(circle2.area, np.pi * 25 * 25) < 0.025)
        self.assertTrue(relative_error(circle2.centroid.x, 250) < 0.025)
        self.assertTrue(relative_error(circle2.centroid.y, 750) < 0.025)
        self.assertEqual(results.dispatches[sorted_idx[2]], "BIG")
        self.assertEqual(results.labels[sorted_idx[2]], ColorClassifier.WHITE)
        self.assertAlmostEqual(results.probas[sorted_idx[2]], 1.0)

        # second square
        square2 = results.polygons[sorted_idx[3]]
        self.assertTrue(relative_error(square2.area, 50 * 50) < 0.025)
        self.assertTrue(relative_error(square2.centroid.x, 750) < 0.025)
        self.assertTrue(relative_error(square2.centroid.y, 750) < 0.025)
        self.assertEqual(results.dispatches[sorted_idx[3]], "BIG")
        self.assertEqual(results.labels[sorted_idx[3]], ColorClassifier.GREY)
        self.assertAlmostEqual(results.probas[sorted_idx[3]], 1.0)

        # check other information
        timing = results.timing
        self.assertEqual(timing.get_phases_hierarchy(), {"workflow.sldc": {
            "detect": {"load": None, "segment": None, "locate": None},
            "merge": None,
            "dispatch_classify": {"dispatch": None, "classify": None}
        }})
示例#16
0
    def testSLDCWorkflowWithCatchAllClassifier(self):
        # pre build components
        segmenter = DumbSegmenter()
        tile_builder = DefaultTileBuilder()
        dispatcher = DumbDispatcher()
        classifier = DumbClassifier()

        builder = SLDCWorkflowBuilder()
        builder.set_segmenter(segmenter)
        builder.set_tile_builder(tile_builder)

        builder.add_catchall_classifier(classifier)

        with self.assertRaises(InvalidBuildingException):
            builder.set_one_shot_dispatcher(dispatcher, {"default": classifier})

        workflow = builder.get()
        self.assertIsInstance(workflow, SLDCWorkflow)
        self.assertIsInstance(workflow._dispatch_classifier._dispatcher, RuleBasedDispatcher)
        self.assertEqual(len(workflow._dispatch_classifier._classifiers), 1)
        self.assertEqual(workflow._dispatch_classifier._classifiers[0], classifier)
        self.assertIsInstance(workflow._dispatch_classifier._dispatcher, RuleBasedDispatcher)
        self.assertEqual(len(workflow._dispatch_classifier._dispatcher._rules), 1)
        self.assertIsInstance(workflow._dispatch_classifier._dispatcher._rules[0], CatchAllRule)
示例#17
0
    def testSquareIncluded(self):
        # generate the image to be processed
        w, h = 2000, 2000
        image = np.zeros((h, w), dtype=np.uint8)

        # locations of the 9 multi-squares
        positions = [
            (w // 7, h // 7),
            (3 * w // 7, h // 7),
            (5 * w // 7, h // 7),
            (w // 7, 3 * h // 7),
            (3 * w // 7, 3 * h // 7),
            (5 * w // 7, 3 * h // 7),
            (w // 7, 5 * h // 7),
            (3 * w // 7, 5 * h // 7),
            (5 * w // 7, 5 * h // 7)
        ]

        for position in positions:
            image = draw_multisquare(image, position, w // 7, color_in=127)

        # Build workflow
        builder = SLDCWorkflowBuilder()

        # Build workflow 1
        builder.set_segmenter(BigShapeSegmenter())
        builder.add_catchall_classifier(DumbClassifier())
        builder.set_tile_size(512, 512)
        workflow1 = builder.get()

        # Build workflow 2
        builder.set_segmenter(SmallSquareSegmenter())
        builder.add_catchall_classifier(DumbClassifier())
        workflow2 = builder.get()

        # Build chaining
        chain_builder = WorkflowChainBuilder()
        chain_builder.set_first_workflow(workflow1, label="big_squares")
        chain_builder.add_executor(workflow2, label="small_squares")
        chain = chain_builder.get()

        # Launch
        chain_info = chain.process(NumpyImage(image))

        # check results
        big_area = (w // 7) ** 2
        small_area = (w / 35) ** 2

        info1 = chain_info["big_squares"]
        self.assertEqual(9, len(info1))
        for object_info in info1:
            self.assertTrue(relative_error(object_info.polygon.area, big_area) < 0.005)
            self.assertEqual("catchall", object_info.dispatch)
            self.assertEqual(1, object_info.label)
            self.assertAlmostEqual(1.0, object_info.proba)

        info2 = chain_info["small_squares"]
        self.assertEqual(36, len(info2))
        for object_info in info2:
            self.assertTrue(relative_error(object_info.polygon.area, small_area) < 0.005)
            self.assertEqual("catchall", object_info.dispatch)
            self.assertEqual(1, object_info.label)
            self.assertAlmostEqual(1.0, object_info.proba)
示例#18
0
    def testSquareAndCircleIncluded(self):
        w, h = 2000, 2000
        image = np.zeros((h, w), dtype=np.uint8)
        # locations of the 9 multi-squares
        shapes = [
            ("c", (w // 7, h // 7)),
            ("s", (3 * w // 7, h // 7)),
            ("s", (5 * w // 7, h // 7)),
            ("s", (w // 7, 3 * h // 7)),
            ("c", (3 * w // 7, 3 * h // 7)),
            ("s", (5 * w // 7, 3 * h // 7)),
            ("c", (w // 7, 5 * h // 7)),
            ("s", (3 * w // 7, 5 * h // 7)),
            ("c", (5 * w // 7, 5 * h // 7))
        ]

        for shape, position in shapes:
            if shape == "c":
                image = draw_multicircle(image, position, w // 7, color_in=87)
            elif shape == "s":
                image = draw_multisquare(image, position, w // 7, color_in=187)

        # Build workflows
        # 1st: find big shapes and dispatch them as circle or square
        # 2nd: find small circles in found circle shapes
        # 3rd: find small squares in found square shape
        builder = SLDCWorkflowBuilder()

        builder.set_segmenter(BigShapeSegmenter())
        builder.add_classifier(CircleDispatch(), DumbClassifier(), dispatching_label="circle")
        builder.add_classifier(SquareDispatch(), DumbClassifier(), dispatching_label="square")
        builder.set_tile_size(512, 512)
        workflow1 = builder.get()

        builder.set_segmenter(SmallCircleSegmenter())
        builder.add_catchall_classifier(DumbClassifier())
        workflow2 = builder.get()

        builder.set_segmenter(SmallSquareSegmenter())
        builder.add_catchall_classifier(DumbClassifier())
        workflow3 = builder.get()

        # Build chain
        chain_builder = WorkflowChainBuilder()
        chain_builder.set_first_workflow(workflow1)
        chain_builder.add_executor(workflow2, filter=CircleShapeFilter())
        chain_builder.add_executor(workflow3, filter=SquareShapeFilter(), n_jobs=2)
        chain = chain_builder.get()

        chain_info = chain.process(NumpyImage(image))

        info1 = chain_info[0]
        self.assertEqual(9, len(info1))
        self.assertEqual(4, len([d for d in info1.dispatches if d == "circle"]))
        self.assertEqual(5, len([d for d in info1.dispatches if d == "square"]))

        info2 = chain_info[1]
        self.assertEqual(16, len(info2))

        info3 = chain_info[2]
        self.assertEqual(20, len(info3))
def main(argv):
    with CytomineJob.from_cli(argv) as job:
        if not os.path.exists(job.parameters.working_path):
            os.makedirs(job.parameters.working_path)

        # create workflow component
        logger = StandardOutputLogger(Logger.INFO)
        random_state = check_random_state(int(job.parameters.rseed))
        tile_builder = CytomineTileBuilder(
            working_path=job.parameters.working_path)
        segmenter = DemoSegmenter(job.parameters.threshold)
        area_rule = ValidAreaRule(job.parameters.min_area)
        classifier = PyxitClassifierAdapter.build_from_pickle(
            job.parameters.pyxit_model_path,
            tile_builder,
            logger,
            random_state=random_state,
            n_jobs=job.parameters.n_jobs,
            working_path=job.parameters.working_path)

        builder = SLDCWorkflowBuilder()
        builder.set_n_jobs(job.parameters.n_jobs)
        builder.set_logger(logger)
        builder.set_overlap(job.parameters.sldc_tile_overlap)
        builder.set_tile_size(job.parameters.sldc_tile_width,
                              job.parameters.sldc_tile_height)
        builder.set_tile_builder(tile_builder)
        builder.set_segmenter(segmenter)
        builder.add_classifier(area_rule,
                               classifier,
                               dispatching_label="valid")
        workflow = builder.get()

        slide = CytomineSlide(job.parameters.cytomine_image_id)
        results = workflow.process(slide)

        # Upload results
        for polygon, label, proba, dispatch in results:
            if label is not None:
                # if image is a window, the polygon must be translated
                if isinstance(slide, ImageWindow):
                    polygon = translate(polygon, slide.abs_offset_x,
                                        slide.abs_offset_y)
                # upload the annotation
                polygon = affine_transform(
                    polygon, [1, 0, 0, -1, 0, slide.image_instance.height])
                annotation = Annotation(
                    location=polygon.wkt,
                    id_image=slide.image_instance.id).save()
                AlgoAnnotationTerm(id_annotation=annotation.id,
                                   id_term=label,
                                   rate=float(proba)).save()