Coverage for src/bob/bio/vein/preprocessor/crop.py: 93%
29 statements
« prev ^ index » next coverage.py v7.6.0, created at 2024-07-12 23:27 +0200
« prev ^ index » next coverage.py v7.6.0, created at 2024-07-12 23:27 +0200
1#!/usr/bin/env python
2# vim: set fileencoding=utf-8 :
5"""Base utilities for pre-cropping images"""
8class Cropper(object):
9 """This is the base class for all croppers
11 It defines the minimum requirements for all derived cropper classes.
14 """
16 def __init__(self):
17 pass
19 def __call__(self, image):
20 """Overwrite this method to implement your masking method
23 Parameters:
25 image (numpy.ndarray): A 2D numpy array of type ``uint8`` with the
26 input image
29 Returns:
31 numpy.ndarray: A 2D numpy array of the same type as the input, with
32 cropped rows and columns as per request
34 """
36 raise NotImplementedError("You must implement the __call__ slot")
39class FixedCrop(Cropper):
40 """Implements cropping using a fixed suppression of border pixels
42 The defaults supress no lines from the image and returns an image like the
43 original. If an :py:class:`bob.bio.vein.database.AnnotatedArray` is passed,
44 then we also check for its ``.metadata['roi']`` component and correct it so
45 that annotated RoI points are consistent on the cropped image.
48 .. note::
50 Before choosing values, note you're responsible for knowing what is the
51 orientation of images fed into this cropper.
54 Parameters:
56 top (:py:class:`int`, optional): Number of lines to suppress from the top
57 of the image. The top of the image corresponds to ``y = 0``.
59 bottom (:py:class:`int`, optional): Number of lines to suppress from the
60 bottom of the image. The bottom of the image corresponds to ``y =
61 height``.
63 left (:py:class:`int`, optional): Number of lines to suppress from the left
64 of the image. The left of the image corresponds to ``x = 0``.
66 right (:py:class:`int`, optional): Number of lines to suppress from the
67 right of the image. The right of the image corresponds to ``x = width``.
69 """
71 def __init__(self, top=0, bottom=0, left=0, right=0):
72 self.top = top
73 self.bottom = bottom
74 self.left = left
75 self.right = right
77 def __call__(self, image):
78 """Returns a big mask
81 Parameters:
83 image (numpy.ndarray): A 2D numpy array of type ``uint8`` with the
84 input image
87 Returns:
89 numpy.ndarray: A 2D numpy array of type boolean with the caculated
90 mask. ``True`` values correspond to regions where the finger is
91 situated
94 """
96 # this should work even if limits are zeros
97 h, w = image.shape
98 retval = image[self.top : h - self.bottom, self.left : w - self.right]
100 if hasattr(retval, "metadata") and "roi" in retval.metadata:
101 # adjust roi points to new cropping
102 retval = retval.copy() # don't override original
103 h, w = retval.shape
104 points = []
105 for y, x in retval.metadata["roi"]:
106 y = max(y - self.top, 0) # adjust
107 y = min(y, h - 1) # verify it is not over the limits
108 x = max(x - self.left, 0) # adjust
109 x = min(x, w - 1) # verify it is not over the limits
110 points.append((y, x))
111 retval.metadata["roi"] = points
113 return retval
116class NoCrop(FixedCrop):
117 """Convenience: same as FixedCrop()"""
119 def __init__(self):
120 super(NoCrop, self).__init__(0, 0, 0, 0)