vkit.mechanism.cropper

  1# Copyright 2022 vkit-x Administrator. All Rights Reserved.
  2#
  3# This project (vkit-x/vkit) is dual-licensed under commercial and SSPL licenses.
  4#
  5# The commercial license gives you the full rights to create and distribute software
  6# on your own terms without any SSPL license obligations. For more information,
  7# please see the "LICENSE_COMMERCIAL.txt" file.
  8#
  9# This project is also available under Server Side Public License (SSPL).
 10# The SSPL licensing is ideal for use cases such as open source projects with
 11# SSPL distribution, student/academic purposes, hobby projects, internal research
 12# projects without external distribution, or other projects where all SSPL
 13# obligations can be met. For more information, please see the "LICENSE_SSPL.txt" file.
 14from typing import Tuple
 15
 16import attrs
 17from numpy.random import Generator as RandomGenerator
 18
 19from vkit.element import (
 20    Point,
 21    Box,
 22    Mask,
 23    ScoreMap,
 24    Image,
 25)
 26
 27
 28@attrs.define
 29class CropperState:
 30    height: int
 31    width: int
 32    pad_value: int
 33    crop_size: int
 34    original_box: Box
 35    target_box: Box
 36    target_core_box: Box
 37    original_core_box: Box
 38
 39    @classmethod
 40    def sample_cropping_positions_along_axis(
 41        cls,
 42        core_size: int,
 43        pad_size: int,
 44        crop_size: int,
 45        length: int,
 46        rng: RandomGenerator,
 47    ):
 48        if core_size <= length:
 49            core_begin = rng.integers(0, length - core_size + 1)
 50            begin = core_begin - pad_size
 51            target_offset = 0
 52            if begin < 0:
 53                target_offset = abs(begin)
 54                begin = 0
 55
 56        else:
 57            begin = 0
 58            target_offset = pad_size
 59            target_offset += rng.integers(0, core_size - length + 1)
 60
 61        end = min(length - 1, begin + (crop_size - target_offset) - 1)
 62        return target_offset, begin, end
 63
 64    @classmethod
 65    def sample_cropping_positions(
 66        cls,
 67        height: int,
 68        width: int,
 69        core_size: int,
 70        pad_size: int,
 71        crop_size: int,
 72        rng: RandomGenerator,
 73    ):
 74        (
 75            target_vert_offset,
 76            original_up,
 77            original_down,
 78        ) = cls.sample_cropping_positions_along_axis(
 79            core_size=core_size,
 80            pad_size=pad_size,
 81            crop_size=crop_size,
 82            length=height,
 83            rng=rng,
 84        )
 85        (
 86            target_hori_offset,
 87            original_left,
 88            original_right,
 89        ) = cls.sample_cropping_positions_along_axis(
 90            core_size=core_size,
 91            pad_size=pad_size,
 92            crop_size=crop_size,
 93            length=width,
 94            rng=rng,
 95        )
 96        return (
 97            target_vert_offset,
 98            original_up,
 99            original_down,
100            target_hori_offset,
101            original_left,
102            original_right,
103        )
104
105    @classmethod
106    def create_from_cropping_positions(
107        cls,
108        height: int,
109        width: int,
110        pad_size: int,
111        pad_value: int,
112        core_size: int,
113        crop_size: int,
114        target_vert_offset: int,
115        original_up: int,
116        original_down: int,
117        target_hori_offset: int,
118        original_left: int,
119        original_right: int,
120    ):
121        original_box = Box(
122            up=original_up,
123            down=original_down,
124            left=original_left,
125            right=original_right,
126        )
127
128        target_box = Box(
129            up=target_vert_offset,
130            down=target_vert_offset + original_box.height - 1,
131            left=target_hori_offset,
132            right=target_hori_offset + original_box.width - 1,
133        )
134
135        target_core_begin = pad_size
136        target_core_end = target_core_begin + core_size - 1
137        target_core_box = Box(
138            up=target_core_begin,
139            down=target_core_end,
140            left=target_core_begin,
141            right=target_core_end,
142        )
143
144        original_core_box = Box(
145            up=original_up + target_core_box.up - target_box.up,
146            down=original_down + target_core_box.down - target_box.down,
147            left=original_left + target_core_box.left - target_box.left,
148            right=original_right + target_core_box.right - target_box.right,
149        )
150
151        return CropperState(
152            height=height,
153            width=width,
154            pad_value=pad_value,
155            crop_size=crop_size,
156            original_box=original_box,
157            target_box=target_box,
158            target_core_box=target_core_box,
159            original_core_box=original_core_box,
160        )
161
162    @classmethod
163    def create_from_random_proposal(
164        cls,
165        shape: Tuple[int, int],
166        core_size: int,
167        pad_size: int,
168        pad_value: int,
169        rng: RandomGenerator,
170    ):
171        height, width = shape
172        crop_size = 2 * pad_size + core_size
173        (
174            target_vert_offset,
175            original_up,
176            original_down,
177            target_hori_offset,
178            original_left,
179            original_right,
180        ) = cls.sample_cropping_positions(
181            height=height,
182            width=width,
183            core_size=core_size,
184            pad_size=pad_size,
185            crop_size=crop_size,
186            rng=rng,
187        )
188        return cls.create_from_cropping_positions(
189            height=height,
190            width=width,
191            pad_size=pad_size,
192            pad_value=pad_value,
193            core_size=core_size,
194            crop_size=crop_size,
195            target_vert_offset=target_vert_offset,
196            original_up=original_up,
197            original_down=original_down,
198            target_hori_offset=target_hori_offset,
199            original_left=original_left,
200            original_right=original_right,
201        )
202
203    @classmethod
204    def create_from_center_point(
205        cls,
206        shape: Tuple[int, int],
207        core_size: int,
208        pad_size: int,
209        pad_value: int,
210        center_point: Point,
211    ):
212        height, width = shape
213        crop_size = 2 * pad_size + core_size
214
215        assert 0 <= center_point.y < height
216        assert 0 <= center_point.x < width
217
218        target_vert_offset = 0
219        up = center_point.y - crop_size // 2
220        down = up + crop_size - 1
221        if up < 0:
222            target_vert_offset = abs(up)
223            up = 0
224        down = min(height - 1, down)
225
226        target_hori_offset = 0
227        left = center_point.x - crop_size // 2
228        right = left + crop_size - 1
229        if left < 0:
230            target_hori_offset = abs(left)
231            left = 0
232        right = min(width - 1, right)
233
234        return CropperState.create_from_cropping_positions(
235            height=height,
236            width=width,
237            pad_size=pad_size,
238            pad_value=pad_value,
239            core_size=core_size,
240            crop_size=crop_size,
241            target_vert_offset=target_vert_offset,
242            original_up=up,
243            original_down=down,
244            target_hori_offset=target_hori_offset,
245            original_left=left,
246            original_right=right,
247        )
248
249    @property
250    def need_post_filling(self):
251        return (
252            self.original_box.height != self.crop_size or self.original_box.width != self.crop_size
253        )
254
255    @property
256    def cropped_shape(self):
257        return (self.crop_size,) * 2
258
259
260class Cropper:
261
262    @classmethod
263    def create_from_random_proposal(
264        cls,
265        shape: Tuple[int, int],
266        core_size: int,
267        pad_size: int,
268        rng: RandomGenerator,
269        pad_value: int = 0,
270    ):
271        cropper_state = CropperState.create_from_random_proposal(
272            shape=shape,
273            core_size=core_size,
274            pad_size=pad_size,
275            pad_value=pad_value,
276            rng=rng,
277        )
278        return Cropper(cropper_state)
279
280    @classmethod
281    def create_from_center_point(
282        cls,
283        shape: Tuple[int, int],
284        core_size: int,
285        pad_size: int,
286        center_point: Point,
287        pad_value: int = 0,
288    ):
289        cropper_state = CropperState.create_from_center_point(
290            shape=shape,
291            core_size=core_size,
292            pad_size=pad_size,
293            pad_value=pad_value,
294            center_point=center_point,
295        )
296        return Cropper(cropper_state)
297
298    def __init__(self, cropper_state: CropperState):
299        self.cropper_state = cropper_state
300
301    @property
302    def original_box(self):
303        return self.cropper_state.original_box
304
305    @property
306    def target_box(self):
307        return self.cropper_state.target_box
308
309    @property
310    def target_core_box(self):
311        return self.cropper_state.target_core_box
312
313    @property
314    def original_core_box(self):
315        return self.cropper_state.original_core_box
316
317    @property
318    def need_post_filling(self):
319        return self.cropper_state.need_post_filling
320
321    @property
322    def crop_size(self):
323        return self.cropper_state.crop_size
324
325    @property
326    def cropped_shape(self):
327        return self.cropper_state.cropped_shape
328
329    @property
330    def pad_value(self):
331        return self.cropper_state.pad_value
332
333    def crop_mask(self, mask: Mask, core_only: bool = False):
334        mask = self.original_box.extract_mask(mask)
335
336        if self.need_post_filling:
337            new_mask = Mask.from_shape(self.cropped_shape)
338            self.target_box.fill_mask(new_mask, mask)
339            mask = new_mask
340
341        if core_only:
342            mask = self.target_core_box.extract_mask(mask)
343            mask = mask.to_box_attached(self.target_core_box)
344
345        return mask
346
347    def crop_score_map(self, score_map: ScoreMap, core_only: bool = False):
348        score_map = self.original_box.extract_score_map(score_map)
349
350        if self.need_post_filling:
351            new_score_map = ScoreMap.from_shape(
352                self.cropped_shape,
353                is_prob=score_map.is_prob,
354            )
355            self.target_box.fill_score_map(new_score_map, score_map)
356            score_map = new_score_map
357
358        if core_only:
359            score_map = self.target_core_box.extract_score_map(score_map)
360            score_map = score_map.to_box_attached(self.target_core_box)
361
362        return score_map
363
364    def crop_image(self, image: Image):
365        image = self.original_box.extract_image(image)
366
367        if self.need_post_filling:
368            new_image = Image.from_shape(
369                self.cropped_shape,
370                num_channels=image.num_channels,
371                value=self.pad_value,
372            )
373            self.target_box.fill_image(new_image, image)
374            image = new_image
375
376        return image
class CropperState:
 30class CropperState:
 31    height: int
 32    width: int
 33    pad_value: int
 34    crop_size: int
 35    original_box: Box
 36    target_box: Box
 37    target_core_box: Box
 38    original_core_box: Box
 39
 40    @classmethod
 41    def sample_cropping_positions_along_axis(
 42        cls,
 43        core_size: int,
 44        pad_size: int,
 45        crop_size: int,
 46        length: int,
 47        rng: RandomGenerator,
 48    ):
 49        if core_size <= length:
 50            core_begin = rng.integers(0, length - core_size + 1)
 51            begin = core_begin - pad_size
 52            target_offset = 0
 53            if begin < 0:
 54                target_offset = abs(begin)
 55                begin = 0
 56
 57        else:
 58            begin = 0
 59            target_offset = pad_size
 60            target_offset += rng.integers(0, core_size - length + 1)
 61
 62        end = min(length - 1, begin + (crop_size - target_offset) - 1)
 63        return target_offset, begin, end
 64
 65    @classmethod
 66    def sample_cropping_positions(
 67        cls,
 68        height: int,
 69        width: int,
 70        core_size: int,
 71        pad_size: int,
 72        crop_size: int,
 73        rng: RandomGenerator,
 74    ):
 75        (
 76            target_vert_offset,
 77            original_up,
 78            original_down,
 79        ) = cls.sample_cropping_positions_along_axis(
 80            core_size=core_size,
 81            pad_size=pad_size,
 82            crop_size=crop_size,
 83            length=height,
 84            rng=rng,
 85        )
 86        (
 87            target_hori_offset,
 88            original_left,
 89            original_right,
 90        ) = cls.sample_cropping_positions_along_axis(
 91            core_size=core_size,
 92            pad_size=pad_size,
 93            crop_size=crop_size,
 94            length=width,
 95            rng=rng,
 96        )
 97        return (
 98            target_vert_offset,
 99            original_up,
100            original_down,
101            target_hori_offset,
102            original_left,
103            original_right,
104        )
105
106    @classmethod
107    def create_from_cropping_positions(
108        cls,
109        height: int,
110        width: int,
111        pad_size: int,
112        pad_value: int,
113        core_size: int,
114        crop_size: int,
115        target_vert_offset: int,
116        original_up: int,
117        original_down: int,
118        target_hori_offset: int,
119        original_left: int,
120        original_right: int,
121    ):
122        original_box = Box(
123            up=original_up,
124            down=original_down,
125            left=original_left,
126            right=original_right,
127        )
128
129        target_box = Box(
130            up=target_vert_offset,
131            down=target_vert_offset + original_box.height - 1,
132            left=target_hori_offset,
133            right=target_hori_offset + original_box.width - 1,
134        )
135
136        target_core_begin = pad_size
137        target_core_end = target_core_begin + core_size - 1
138        target_core_box = Box(
139            up=target_core_begin,
140            down=target_core_end,
141            left=target_core_begin,
142            right=target_core_end,
143        )
144
145        original_core_box = Box(
146            up=original_up + target_core_box.up - target_box.up,
147            down=original_down + target_core_box.down - target_box.down,
148            left=original_left + target_core_box.left - target_box.left,
149            right=original_right + target_core_box.right - target_box.right,
150        )
151
152        return CropperState(
153            height=height,
154            width=width,
155            pad_value=pad_value,
156            crop_size=crop_size,
157            original_box=original_box,
158            target_box=target_box,
159            target_core_box=target_core_box,
160            original_core_box=original_core_box,
161        )
162
163    @classmethod
164    def create_from_random_proposal(
165        cls,
166        shape: Tuple[int, int],
167        core_size: int,
168        pad_size: int,
169        pad_value: int,
170        rng: RandomGenerator,
171    ):
172        height, width = shape
173        crop_size = 2 * pad_size + core_size
174        (
175            target_vert_offset,
176            original_up,
177            original_down,
178            target_hori_offset,
179            original_left,
180            original_right,
181        ) = cls.sample_cropping_positions(
182            height=height,
183            width=width,
184            core_size=core_size,
185            pad_size=pad_size,
186            crop_size=crop_size,
187            rng=rng,
188        )
189        return cls.create_from_cropping_positions(
190            height=height,
191            width=width,
192            pad_size=pad_size,
193            pad_value=pad_value,
194            core_size=core_size,
195            crop_size=crop_size,
196            target_vert_offset=target_vert_offset,
197            original_up=original_up,
198            original_down=original_down,
199            target_hori_offset=target_hori_offset,
200            original_left=original_left,
201            original_right=original_right,
202        )
203
204    @classmethod
205    def create_from_center_point(
206        cls,
207        shape: Tuple[int, int],
208        core_size: int,
209        pad_size: int,
210        pad_value: int,
211        center_point: Point,
212    ):
213        height, width = shape
214        crop_size = 2 * pad_size + core_size
215
216        assert 0 <= center_point.y < height
217        assert 0 <= center_point.x < width
218
219        target_vert_offset = 0
220        up = center_point.y - crop_size // 2
221        down = up + crop_size - 1
222        if up < 0:
223            target_vert_offset = abs(up)
224            up = 0
225        down = min(height - 1, down)
226
227        target_hori_offset = 0
228        left = center_point.x - crop_size // 2
229        right = left + crop_size - 1
230        if left < 0:
231            target_hori_offset = abs(left)
232            left = 0
233        right = min(width - 1, right)
234
235        return CropperState.create_from_cropping_positions(
236            height=height,
237            width=width,
238            pad_size=pad_size,
239            pad_value=pad_value,
240            core_size=core_size,
241            crop_size=crop_size,
242            target_vert_offset=target_vert_offset,
243            original_up=up,
244            original_down=down,
245            target_hori_offset=target_hori_offset,
246            original_left=left,
247            original_right=right,
248        )
249
250    @property
251    def need_post_filling(self):
252        return (
253            self.original_box.height != self.crop_size or self.original_box.width != self.crop_size
254        )
255
256    @property
257    def cropped_shape(self):
258        return (self.crop_size,) * 2
CropperState( height: int, width: int, pad_value: int, crop_size: int, original_box: vkit.element.box.Box, target_box: vkit.element.box.Box, target_core_box: vkit.element.box.Box, original_core_box: vkit.element.box.Box)
 2def __init__(self, height, width, pad_value, crop_size, original_box, target_box, target_core_box, original_core_box):
 3    self.height = height
 4    self.width = width
 5    self.pad_value = pad_value
 6    self.crop_size = crop_size
 7    self.original_box = original_box
 8    self.target_box = target_box
 9    self.target_core_box = target_core_box
10    self.original_core_box = original_core_box

Method generated by attrs for class CropperState.

@classmethod
def sample_cropping_positions_along_axis( cls, core_size: int, pad_size: int, crop_size: int, length: int, rng: numpy.random._generator.Generator):
40    @classmethod
41    def sample_cropping_positions_along_axis(
42        cls,
43        core_size: int,
44        pad_size: int,
45        crop_size: int,
46        length: int,
47        rng: RandomGenerator,
48    ):
49        if core_size <= length:
50            core_begin = rng.integers(0, length - core_size + 1)
51            begin = core_begin - pad_size
52            target_offset = 0
53            if begin < 0:
54                target_offset = abs(begin)
55                begin = 0
56
57        else:
58            begin = 0
59            target_offset = pad_size
60            target_offset += rng.integers(0, core_size - length + 1)
61
62        end = min(length - 1, begin + (crop_size - target_offset) - 1)
63        return target_offset, begin, end
@classmethod
def sample_cropping_positions( cls, height: int, width: int, core_size: int, pad_size: int, crop_size: int, rng: numpy.random._generator.Generator):
 65    @classmethod
 66    def sample_cropping_positions(
 67        cls,
 68        height: int,
 69        width: int,
 70        core_size: int,
 71        pad_size: int,
 72        crop_size: int,
 73        rng: RandomGenerator,
 74    ):
 75        (
 76            target_vert_offset,
 77            original_up,
 78            original_down,
 79        ) = cls.sample_cropping_positions_along_axis(
 80            core_size=core_size,
 81            pad_size=pad_size,
 82            crop_size=crop_size,
 83            length=height,
 84            rng=rng,
 85        )
 86        (
 87            target_hori_offset,
 88            original_left,
 89            original_right,
 90        ) = cls.sample_cropping_positions_along_axis(
 91            core_size=core_size,
 92            pad_size=pad_size,
 93            crop_size=crop_size,
 94            length=width,
 95            rng=rng,
 96        )
 97        return (
 98            target_vert_offset,
 99            original_up,
100            original_down,
101            target_hori_offset,
102            original_left,
103            original_right,
104        )
@classmethod
def create_from_cropping_positions( cls, height: int, width: int, pad_size: int, pad_value: int, core_size: int, crop_size: int, target_vert_offset: int, original_up: int, original_down: int, target_hori_offset: int, original_left: int, original_right: int):
106    @classmethod
107    def create_from_cropping_positions(
108        cls,
109        height: int,
110        width: int,
111        pad_size: int,
112        pad_value: int,
113        core_size: int,
114        crop_size: int,
115        target_vert_offset: int,
116        original_up: int,
117        original_down: int,
118        target_hori_offset: int,
119        original_left: int,
120        original_right: int,
121    ):
122        original_box = Box(
123            up=original_up,
124            down=original_down,
125            left=original_left,
126            right=original_right,
127        )
128
129        target_box = Box(
130            up=target_vert_offset,
131            down=target_vert_offset + original_box.height - 1,
132            left=target_hori_offset,
133            right=target_hori_offset + original_box.width - 1,
134        )
135
136        target_core_begin = pad_size
137        target_core_end = target_core_begin + core_size - 1
138        target_core_box = Box(
139            up=target_core_begin,
140            down=target_core_end,
141            left=target_core_begin,
142            right=target_core_end,
143        )
144
145        original_core_box = Box(
146            up=original_up + target_core_box.up - target_box.up,
147            down=original_down + target_core_box.down - target_box.down,
148            left=original_left + target_core_box.left - target_box.left,
149            right=original_right + target_core_box.right - target_box.right,
150        )
151
152        return CropperState(
153            height=height,
154            width=width,
155            pad_value=pad_value,
156            crop_size=crop_size,
157            original_box=original_box,
158            target_box=target_box,
159            target_core_box=target_core_box,
160            original_core_box=original_core_box,
161        )
@classmethod
def create_from_random_proposal( cls, shape: Tuple[int, int], core_size: int, pad_size: int, pad_value: int, rng: numpy.random._generator.Generator):
163    @classmethod
164    def create_from_random_proposal(
165        cls,
166        shape: Tuple[int, int],
167        core_size: int,
168        pad_size: int,
169        pad_value: int,
170        rng: RandomGenerator,
171    ):
172        height, width = shape
173        crop_size = 2 * pad_size + core_size
174        (
175            target_vert_offset,
176            original_up,
177            original_down,
178            target_hori_offset,
179            original_left,
180            original_right,
181        ) = cls.sample_cropping_positions(
182            height=height,
183            width=width,
184            core_size=core_size,
185            pad_size=pad_size,
186            crop_size=crop_size,
187            rng=rng,
188        )
189        return cls.create_from_cropping_positions(
190            height=height,
191            width=width,
192            pad_size=pad_size,
193            pad_value=pad_value,
194            core_size=core_size,
195            crop_size=crop_size,
196            target_vert_offset=target_vert_offset,
197            original_up=original_up,
198            original_down=original_down,
199            target_hori_offset=target_hori_offset,
200            original_left=original_left,
201            original_right=original_right,
202        )
@classmethod
def create_from_center_point( cls, shape: Tuple[int, int], core_size: int, pad_size: int, pad_value: int, center_point: vkit.element.point.Point):
204    @classmethod
205    def create_from_center_point(
206        cls,
207        shape: Tuple[int, int],
208        core_size: int,
209        pad_size: int,
210        pad_value: int,
211        center_point: Point,
212    ):
213        height, width = shape
214        crop_size = 2 * pad_size + core_size
215
216        assert 0 <= center_point.y < height
217        assert 0 <= center_point.x < width
218
219        target_vert_offset = 0
220        up = center_point.y - crop_size // 2
221        down = up + crop_size - 1
222        if up < 0:
223            target_vert_offset = abs(up)
224            up = 0
225        down = min(height - 1, down)
226
227        target_hori_offset = 0
228        left = center_point.x - crop_size // 2
229        right = left + crop_size - 1
230        if left < 0:
231            target_hori_offset = abs(left)
232            left = 0
233        right = min(width - 1, right)
234
235        return CropperState.create_from_cropping_positions(
236            height=height,
237            width=width,
238            pad_size=pad_size,
239            pad_value=pad_value,
240            core_size=core_size,
241            crop_size=crop_size,
242            target_vert_offset=target_vert_offset,
243            original_up=up,
244            original_down=down,
245            target_hori_offset=target_hori_offset,
246            original_left=left,
247            original_right=right,
248        )
class Cropper:
261class Cropper:
262
263    @classmethod
264    def create_from_random_proposal(
265        cls,
266        shape: Tuple[int, int],
267        core_size: int,
268        pad_size: int,
269        rng: RandomGenerator,
270        pad_value: int = 0,
271    ):
272        cropper_state = CropperState.create_from_random_proposal(
273            shape=shape,
274            core_size=core_size,
275            pad_size=pad_size,
276            pad_value=pad_value,
277            rng=rng,
278        )
279        return Cropper(cropper_state)
280
281    @classmethod
282    def create_from_center_point(
283        cls,
284        shape: Tuple[int, int],
285        core_size: int,
286        pad_size: int,
287        center_point: Point,
288        pad_value: int = 0,
289    ):
290        cropper_state = CropperState.create_from_center_point(
291            shape=shape,
292            core_size=core_size,
293            pad_size=pad_size,
294            pad_value=pad_value,
295            center_point=center_point,
296        )
297        return Cropper(cropper_state)
298
299    def __init__(self, cropper_state: CropperState):
300        self.cropper_state = cropper_state
301
302    @property
303    def original_box(self):
304        return self.cropper_state.original_box
305
306    @property
307    def target_box(self):
308        return self.cropper_state.target_box
309
310    @property
311    def target_core_box(self):
312        return self.cropper_state.target_core_box
313
314    @property
315    def original_core_box(self):
316        return self.cropper_state.original_core_box
317
318    @property
319    def need_post_filling(self):
320        return self.cropper_state.need_post_filling
321
322    @property
323    def crop_size(self):
324        return self.cropper_state.crop_size
325
326    @property
327    def cropped_shape(self):
328        return self.cropper_state.cropped_shape
329
330    @property
331    def pad_value(self):
332        return self.cropper_state.pad_value
333
334    def crop_mask(self, mask: Mask, core_only: bool = False):
335        mask = self.original_box.extract_mask(mask)
336
337        if self.need_post_filling:
338            new_mask = Mask.from_shape(self.cropped_shape)
339            self.target_box.fill_mask(new_mask, mask)
340            mask = new_mask
341
342        if core_only:
343            mask = self.target_core_box.extract_mask(mask)
344            mask = mask.to_box_attached(self.target_core_box)
345
346        return mask
347
348    def crop_score_map(self, score_map: ScoreMap, core_only: bool = False):
349        score_map = self.original_box.extract_score_map(score_map)
350
351        if self.need_post_filling:
352            new_score_map = ScoreMap.from_shape(
353                self.cropped_shape,
354                is_prob=score_map.is_prob,
355            )
356            self.target_box.fill_score_map(new_score_map, score_map)
357            score_map = new_score_map
358
359        if core_only:
360            score_map = self.target_core_box.extract_score_map(score_map)
361            score_map = score_map.to_box_attached(self.target_core_box)
362
363        return score_map
364
365    def crop_image(self, image: Image):
366        image = self.original_box.extract_image(image)
367
368        if self.need_post_filling:
369            new_image = Image.from_shape(
370                self.cropped_shape,
371                num_channels=image.num_channels,
372                value=self.pad_value,
373            )
374            self.target_box.fill_image(new_image, image)
375            image = new_image
376
377        return image
Cropper(cropper_state: vkit.mechanism.cropper.CropperState)
299    def __init__(self, cropper_state: CropperState):
300        self.cropper_state = cropper_state
@classmethod
def create_from_random_proposal( cls, shape: Tuple[int, int], core_size: int, pad_size: int, rng: numpy.random._generator.Generator, pad_value: int = 0):
263    @classmethod
264    def create_from_random_proposal(
265        cls,
266        shape: Tuple[int, int],
267        core_size: int,
268        pad_size: int,
269        rng: RandomGenerator,
270        pad_value: int = 0,
271    ):
272        cropper_state = CropperState.create_from_random_proposal(
273            shape=shape,
274            core_size=core_size,
275            pad_size=pad_size,
276            pad_value=pad_value,
277            rng=rng,
278        )
279        return Cropper(cropper_state)
@classmethod
def create_from_center_point( cls, shape: Tuple[int, int], core_size: int, pad_size: int, center_point: vkit.element.point.Point, pad_value: int = 0):
281    @classmethod
282    def create_from_center_point(
283        cls,
284        shape: Tuple[int, int],
285        core_size: int,
286        pad_size: int,
287        center_point: Point,
288        pad_value: int = 0,
289    ):
290        cropper_state = CropperState.create_from_center_point(
291            shape=shape,
292            core_size=core_size,
293            pad_size=pad_size,
294            pad_value=pad_value,
295            center_point=center_point,
296        )
297        return Cropper(cropper_state)
def crop_mask(self, mask: vkit.element.mask.Mask, core_only: bool = False):
334    def crop_mask(self, mask: Mask, core_only: bool = False):
335        mask = self.original_box.extract_mask(mask)
336
337        if self.need_post_filling:
338            new_mask = Mask.from_shape(self.cropped_shape)
339            self.target_box.fill_mask(new_mask, mask)
340            mask = new_mask
341
342        if core_only:
343            mask = self.target_core_box.extract_mask(mask)
344            mask = mask.to_box_attached(self.target_core_box)
345
346        return mask
def crop_score_map( self, score_map: vkit.element.score_map.ScoreMap, core_only: bool = False):
348    def crop_score_map(self, score_map: ScoreMap, core_only: bool = False):
349        score_map = self.original_box.extract_score_map(score_map)
350
351        if self.need_post_filling:
352            new_score_map = ScoreMap.from_shape(
353                self.cropped_shape,
354                is_prob=score_map.is_prob,
355            )
356            self.target_box.fill_score_map(new_score_map, score_map)
357            score_map = new_score_map
358
359        if core_only:
360            score_map = self.target_core_box.extract_score_map(score_map)
361            score_map = score_map.to_box_attached(self.target_core_box)
362
363        return score_map
def crop_image(self, image: vkit.element.image.Image):
365    def crop_image(self, image: Image):
366        image = self.original_box.extract_image(image)
367
368        if self.need_post_filling:
369            new_image = Image.from_shape(
370                self.cropped_shape,
371                num_channels=image.num_channels,
372                value=self.pad_value,
373            )
374            self.target_box.fill_image(new_image, image)
375            image = new_image
376
377        return image