Example #1
0
 def test_get_box_coord(self):
     """
     Bounding box successfully returns the array of the box in coordinates version.
     """
     box = BoundingBox(15, 16, 17, 18)
     self.assertEqual(box.get_box_coord(),
                      [[15, 16], [32, 16], [15, 34], [32, 34]])
    def _process_resource(self, image):
        """
        Processes the specified image in order to get the bounding boxes for the faces.
        :param image: image resource pointing to a valid URI or containing the image content.
                    If the image is not loaded but is pointing to a valid URI, this method
                    will try to load the image from the URI in grayscale.
        :return: an array of bounding boxes
        """

        image_content = self._get_loaded_image_content(image, as_gray=True)

        # The 1 in the second argument indicates that we should upsample the image
        # 1 time.  This will make everything bigger and allow us to detect more
        # faces.
        detections = self.detector(image_content, 1)

        metadata_content = []

        for i, d in enumerate(detections):
            bounding_box = BoundingBox(d.left(), d.top(),
                                       d.right() - d.left(),
                                       d.bottom() - d.top())
            bounding_box.fit_in_size(image.get_size())
            metadata_content.append(bounding_box)

        return metadata_content
Example #3
0
 def test_expand(self):
     """
     Expansion of bounding box.
     """
     box1 = BoundingBox(3, 3, 100, 100)
     box1.expand()  # expand a default of 20%
     self.assertEqual(
         box1.get_box(),
         [-7, -7, 120, 120])  # If you see something weird here,
Example #4
0
    def test_intersection_with_other_boundingbox(self):
        """
        Bounding box intersects itself with other bounding boxes.
        """
        for rect_set in self.rect_sets:
            rect1 = rect_set[0]
            rect2 = rect_set[1]
            expectedArea = rect_set[2]
            expectedPercentage = rect_set[3]

            box1 = BoundingBox(*rect1)
            box2 = BoundingBox(*rect2)

            intersection = box1.intersect_with(box2)
            number_of_common_pixels = intersection.get_area()

            # Which one is the smaller rectangle?
            area_box1 = box1.get_area()
            area_box2 = box2.get_area()

            lesser_area = min(area_box1, area_box2)
            percentage = round((number_of_common_pixels / lesser_area) * 100,
                               2)

            self.assertEqual(number_of_common_pixels, expectedArea)
            self.assertEqual(percentage, expectedPercentage)
    def test_apply_proportion(self):
        """
        ProportionSizeNormalizer works correctly with proportions for bounding boxes
        """

        bounding_boxes = [
            BoundingBox(100, 100, 500, 500),
            BoundingBox(50, 100, 200, 500)
        ]

        normalizer = ProportionSizeNormalizer(0.5, 0.3)

        for bounding_box in bounding_boxes:
            result = normalizer.apply(bounding_box)

            result_should_be = [int(bounding_box.get_box()[0] * 0.5), int(bounding_box.get_box()[1] * 0.3),
                                int(bounding_box.get_box()[2] * 0.5), int(bounding_box.get_box()[3] * 0.3)]

            self.assertEqual(result.get_box(), result_should_be)
Example #6
0
    def _process_resource(self, image):
        """
        Processes the specified image in order to get the bounding boxes for the faces.
        :param image: image resource pointing to a valid URI or containing the image content.
                    If the image is not loaded but is pointing to a valid URI, this method
                    will try to load the image from the URI in grayscale.
        :return: an array of bounding boxes.
        """

        image_content = self._get_loaded_image_content(image, as_gray=True)

        detections = self.detector.detectMultiScale(image_content, 1.3, 5)

        metadata_content = []

        for (x, y, width, height) in detections:
            bounding_box = BoundingBox(int(x), int(y), int(width), int(height))
            bounding_box.fit_in_size(image.get_size())
            metadata_content.append(bounding_box)

        return metadata_content
Example #7
0
    def test_bounding_box_from_string(self):
        """
        Create a bounding box from a string.
        """
        bbox_string = "22,34,122,432"
        bbox = BoundingBox.from_string(bbox_string)

        self.assertEqual(bbox.get_box(), [22, 34, 122, 432])

        bbox_string = "22, 34,122,432"
        bbox = BoundingBox.from_string(bbox_string)

        self.assertEqual(bbox.get_box(), [22, 34, 122, 432])

        bbox_string = "22, 34, 122, 432"
        bbox = BoundingBox.from_string(bbox_string)

        self.assertEqual(bbox.get_box(), [22, 34, 122, 432])

        bbox_string = "   22, 34, 122, 432   "
        bbox = BoundingBox.from_string(bbox_string)

        self.assertEqual(bbox.get_box(), [22, 34, 122, 432])

        with self.assertRaises(Exception):
            bbox_string = "22,34,122 432"
            bbox = BoundingBox.from_string(bbox_string)

        with self.assertRaises(Exception):
            bbox_string = "22,34  122 432"
            bbox = BoundingBox.from_string(bbox_string)
Example #8
0
    def apply(self, bounding_box):
        """
        Applies the resize normalizer to the specified bounding box.
        :param bounding_box: Bounding box to resize.
        :return: A bounding box clone resized
        """

        box = bounding_box.get_box()

        return BoundingBox(int(box[0] * self.proportion_width),
                           int(box[1] * self.proportion_height),
                           int(box[2] * self.proportion_width),
                           int(box[3] * self.proportion_height))
Example #9
0
 def test_get_components(self):
     """
     Bounding box isolated components are accessible.
     """
     box = BoundingBox(15, 16, 17, 18)
     self.assertEqual(box.get_x(), 15)
     self.assertEqual(box.get_y(), 16)
     self.assertEqual(box.get_width(), 17)
     self.assertEqual(box.get_height(), 18)
Example #10
0
    def _process_resource(self, image):
        """
        Processes the specified image in order to get the bounding boxes for the faces.
        :param image: image resource pointing to a valid URI or containing the image content.
                    If the image is not loaded but is pointing to a valid URI, this method
                    will try to load the image from the URI in grayscale.
        :return: an array of bounding boxes
        """
        #  This is a required step because MTCNN has a limitation on the size it can process.
        # 1024x1024 is an affordable size for MTCNN.

        if image.get_size() > NORMALIZE_IMAGES_SIZE:
            normalized_image = self.size_normalizer.apply(image)
            proportions = [
                x / y if y else 1
                for x, y in zip(image.get_size(), normalized_image.get_size())
            ]
            proportion_bbox_normalizer = ProportionSizeNormalizer(*proportions)

        else:
            normalized_image = image
            proportion_bbox_normalizer = None

        image_content = self._get_loaded_image_content(normalized_image,
                                                       as_gray=False)

        detections, points = self.detector.detect_faces(image_content)

        metadata_content = []

        for detection in detections:
            raw_bbox = list([int(x) for x in detection[:4]])

            normalized_bounding_box = BoundingBox(raw_bbox[0], raw_bbox[1],
                                                  raw_bbox[2] - raw_bbox[0],
                                                  raw_bbox[3] - raw_bbox[1])

            # Bounding boxes are relative to the normalized image. We need to resize them back to the original size
            if proportion_bbox_normalizer is not None:
                bounding_box = proportion_bbox_normalizer.apply(
                    normalized_bounding_box)
            else:
                bounding_box = normalized_bounding_box

            bounding_box.fit_in_size(image.get_size())
            metadata_content.append(bounding_box)

        return metadata_content
    def _crop_by_bounding_box(image, bounding_box_text=None):
        """
        Crops the image by the specified bounding box. If no bounding box is specified, the image
        will be returned without any filtering.
        :param image: image to crop.
        :param bounding_box_text: bounding box to crop by. None to disable cropping.
        :return: the image filtered or the original image in case the bounding box is None.
        """

        if bounding_box_text is not None:
            try:
                bounding_box_text = BoundingBox.from_string(bounding_box_text)
                bounding_box_text.fit_in_size(image.get_size())
                image = image.crop_image(bounding_box_text,
                                         "Cropped by boundingbox")

            except Exception as ex:
                raise InvalidRequest(
                    "The bounding box format is not valid. "
                    "Format must be: bounding_box=x,y,width,height")

        return image
Example #12
0
 def test_center(self):
     """
     Bounding box knows its center point.
     """
     box = BoundingBox(10, 10, 20, 20)
     self.assertEqual(box.get_center(), [20, 20])
Example #13
0
 def test_get_box(self):
     """
     Bounding box successfully returns the array of the box dimensions.
     """
     box = BoundingBox(15, 16, 17, 18)
     self.assertEqual(box.get_box(), [15, 16, 17, 18])
Example #14
0
    def test_fit_in_size(self):
        """
        Bounding box is able to adapt itself to specified bounds.
        """
        image_size = [300, 300]

        # Case1 all out of bounds
        box1 = BoundingBox(-1, -1, 302, 302)
        box1.fit_in_size(image_size)
        self.assertEqual(box1.get_box(), [0, 0, 300, 300])

        # Case2 top left out of bounds
        box1 = BoundingBox(-1, -1, 301, 301)
        box1.fit_in_size(image_size)
        self.assertEqual(box1.get_box(), [0, 0, 300, 300])

        # Case left out of bounds
        box1 = BoundingBox(-15, 10, 100, 100)
        box1.fit_in_size(image_size)
        self.assertEqual(box1.get_box(), [0, 10, 85, 100])

        # Case top out of bounds
        box1 = BoundingBox(15, -10, 100, 100)
        box1.fit_in_size(image_size)
        self.assertEqual(box1.get_box(), [15, 0, 100, 90])

        # Case width out of bounds
        box1 = BoundingBox(15, 0, 290, 100)
        box1.fit_in_size(image_size)
        self.assertEqual(box1.get_box(), [15, 0, 285, 100])

        # Case height out of bounds
        box1 = BoundingBox(15, 15, 200, 290)
        box1.fit_in_size(image_size)
        self.assertEqual(box1.get_box(), [15, 15, 200, 285])
Example #15
0
 def test_get_numpy_format(self):
     """
     Bounding box numpy format is correct.
     """
     box = BoundingBox(15, 16, 17, 18)
     self.assertEqual(box.get_numpy_format(), [16, 34, 15, 32])
Example #16
0
 def test_area(self):
     """
     Bounding box knows its area.
     """
     box = BoundingBox(10, 10, 20, 20)
     self.assertEqual(box.get_area(), 400)
Example #17
0
 def test_str(self):
     """
     Bounding box describes itself correctly.
     """
     box = BoundingBox(15, 16, 17, 18)
     self.assertEqual(box.__str__(), "[15, 16, 17, 18]")