We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Outdated example
Outdated example on the geometry.transform.**crop_and_resize**() function

Following the clockwise order for the corners it should be:

`       >>> boxes = torch.tensor([[
                [1., 1.],
                [1., 2.],
                [2., 2.],
                [2., 1.],
            ]])  # 1x4x2`

Instead of the current:
`        >>> boxes = torch.tensor([[
                [1., 1.],
                [1., 2.],
                [2., 1.],
                [2., 2.],
            ]])  # 1x4x2`

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kornia/geometry/transform/crop.py`
Content:
```
1 from typing import Tuple, Union
2 
3 import torch
4 
5 from kornia.geometry.transform.imgwarp import (
6     warp_perspective, get_perspective_transform
7 )
8 
9 __all__ = [
10     "crop_and_resize",
11     "crop_by_boxes",
12     "center_crop",
13 ]
14 
15 
16 def crop_and_resize(tensor: torch.Tensor, boxes: torch.Tensor, size: Tuple[int, int],
17                     return_transform: bool = False) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:
18     r"""Extracts crops from the input tensor and resizes them.
19     Args:
20         tensor (torch.Tensor): the reference tensor of shape BxCxHxW.
21         boxes (torch.Tensor): a tensor containing the coordinates of the
22           bounding boxes to be extracted. The tensor must have the shape
23           of Bx4x2, where each box is defined in the following (clockwise)
24           order: top-left, top-right, bottom-right and bottom-left. The
25           coordinates must be in the x, y order.
26         size (Tuple[int, int]): a tuple with the height and width that will be
27           used to resize the extracted patches.
28     Returns:
29         torch.Tensor: tensor containing the patches with shape BxN1xN2
30     Example:
31         >>> input = torch.tensor([[
32                 [1., 2., 3., 4.],
33                 [5., 6., 7., 8.],
34                 [9., 10., 11., 12.],
35                 [13., 14., 15., 16.],
36             ]])
37         >>> boxes = torch.tensor([[
38                 [1., 1.],
39                 [1., 2.],
40                 [2., 1.],
41                 [2., 2.],
42             ]])  # 1x4x2
43         >>> kornia.crop_and_resize(input, boxes, (2, 2))
44         tensor([[[ 6.0000,  7.0000],
45                  [ 10.0000, 11.0000]]])
46     """
47     if not torch.is_tensor(tensor):
48         raise TypeError("Input tensor type is not a torch.Tensor. Got {}"
49                         .format(type(tensor)))
50     if not torch.is_tensor(boxes):
51         raise TypeError("Input boxes type is not a torch.Tensor. Got {}"
52                         .format(type(boxes)))
53     if not len(tensor.shape) in (3, 4,):
54         raise ValueError("Input tensor must be in the shape of CxHxW or "
55                          "BxCxHxW. Got {}".format(tensor.shape))
56     if not isinstance(size, (tuple, list,)) and len(size) == 2:
57         raise ValueError("Input size must be a tuple/list of length 2. Got {}"
58                          .format(size))
59     # unpack input data
60     dst_h: torch.Tensor = torch.tensor(size[0])
61     dst_w: torch.Tensor = torch.tensor(size[1])
62 
63     # [x, y] origin
64     # top-left, top-right, bottom-right, bottom-left
65     points_src: torch.Tensor = boxes
66 
67     # [x, y] destination
68     # top-left, top-right, bottom-right, bottom-left
69     points_dst: torch.Tensor = torch.tensor([[
70         [0, 0],
71         [dst_w - 1, 0],
72         [dst_w - 1, dst_h - 1],
73         [0, dst_h - 1],
74     ]]).repeat(points_src.shape[0], 1, 1)
75 
76     return crop_by_boxes(tensor, points_src, points_dst, return_transform=return_transform)
77 
78 
79 def center_crop(tensor: torch.Tensor, size: Tuple[int, int],
80                 return_transform: bool = False) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:
81     r"""Crops the given tensor at the center.
82 
83     Args:
84         tensor (torch.Tensor): the input tensor with shape (C, H, W) or
85           (B, C, H, W).
86         size (Tuple[int, int]): a tuple with the expected height and width
87           of the output patch.
88 
89     Returns:
90         torch.Tensor: the output tensor with patches.
91 
92     Examples:
93         >>> input = torch.tensor([[
94                 [1., 2., 3., 4.],
95                 [5., 6., 7., 8.],
96                 [9., 10., 11., 12.],
97                 [13., 14., 15., 16.],
98              ]])
99         >>> kornia.center_crop(input, (2, 4))
100         tensor([[[ 5.0000,  6.0000,  7.0000,  8.0000],
101                  [ 9.0000, 10.0000, 11.0000, 12.0000]]])
102     """
103     if not torch.is_tensor(tensor):
104         raise TypeError("Input tensor type is not a torch.Tensor. Got {}"
105                         .format(type(tensor)))
106 
107     if not len(tensor.shape) in (3, 4,):
108         raise ValueError("Input tensor must be in the shape of CxHxW or "
109                          "BxCxHxW. Got {}".format(tensor.shape))
110 
111     if not isinstance(size, (tuple, list,)) and len(size) == 2:
112         raise ValueError("Input size must be a tuple/list of length 2. Got {}"
113                          .format(size))
114 
115     # unpack input sizes
116     dst_h, dst_w = size
117     src_h, src_w = tensor.shape[-2:]
118 
119     # compute start/end offsets
120     dst_h_half = dst_h / 2
121     dst_w_half = dst_w / 2
122     src_h_half = src_h / 2
123     src_w_half = src_w / 2
124 
125     start_x = src_w_half - dst_w_half
126     start_y = src_h_half - dst_h_half
127 
128     end_x = start_x + dst_w - 1
129     end_y = start_y + dst_h - 1
130     # [y, x] origin
131     # top-left, top-right, bottom-right, bottom-left
132     points_src: torch.Tensor = torch.tensor([[
133         [start_x, start_y],
134         [end_x, start_y],
135         [end_x, end_y],
136         [start_x, end_y],
137     ]])
138 
139     # [y, x] destination
140     # top-left, top-right, bottom-right, bottom-left
141     points_dst: torch.Tensor = torch.tensor([[
142         [0, 0],
143         [dst_w - 1, 0],
144         [dst_w - 1, dst_h - 1],
145         [0, dst_h - 1],
146     ]]).repeat(points_src.shape[0], 1, 1)
147     return crop_by_boxes(tensor, points_src, points_dst, return_transform=return_transform)
148 
149 
150 def crop_by_boxes(tensor, src_box, dst_box,
151                   return_transform: bool = False) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:
152     """A wrapper performs crop transform with bounding boxes.
153 
154     """
155     if tensor.ndimension() not in [3, 4]:
156         raise TypeError("Only tensor with shape (C, H, W) and (B, C, H, W) supported. Got %s" % str(tensor.shape))
157     # warping needs data in the shape of BCHW
158     is_unbatched: bool = tensor.ndimension() == 3
159     if is_unbatched:
160         tensor = torch.unsqueeze(tensor, dim=0)
161 
162     # compute transformation between points and warp
163     dst_trans_src: torch.Tensor = get_perspective_transform(
164         src_box.to(tensor.device).to(tensor.dtype),
165         dst_box.to(tensor.device).to(tensor.dtype)
166     )
167     # simulate broadcasting
168     dst_trans_src = dst_trans_src.expand(tensor.shape[0], -1, -1)
169 
170     bbox = _infer_bounding_box(dst_box)
171     patches: torch.Tensor = warp_perspective(
172         tensor, dst_trans_src, (int(bbox[0].int().data.item()), int(bbox[1].int().data.item())))
173 
174     # return in the original shape
175     if is_unbatched:
176         patches = torch.squeeze(patches, dim=0)
177 
178     if return_transform:
179         return patches, dst_trans_src
180 
181     return patches
182 
183 
184 def _infer_bounding_box(boxes: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
185     r"""Auto-infer the output sizes.
186 
187     Args:
188         boxes (torch.Tensor): a tensor containing the coordinates of the
189           bounding boxes to be extracted. The tensor must have the shape
190           of Bx4x2, where each box is defined in the following (clockwise)
191           order: top-left, top-right, bottom-right, bottom-left. The
192           coordinates must be in the x, y order.
193 
194     Returns:
195         (torch.Tensor, torch.Tensor): tensor containing the patches with shape BxN1xN2
196 
197     Example:
198         >>> boxes = torch.tensor([[
199                 [1., 1.],
200                 [2., 1.],
201                 [2., 2.],
202                 [1., 2.],
203             ]])  # 1x4x2
204         >>> _infer_bounding_box(boxes)
205         (2, 2)
206     """
207     assert torch.allclose((boxes[:, 1, 0] - boxes[:, 0, 0] + 1), (boxes[:, 2, 0] - boxes[:, 3, 0] + 1)), \
208         "Boxes must have be square, while get widths %s and %s" % \
209         (str(boxes[:, 1, 0] - boxes[:, 0, 0] + 1), str(boxes[:, 2, 0] - boxes[:, 3, 0] + 1))
210     assert torch.allclose((boxes[:, 2, 1] - boxes[:, 0, 1] + 1), (boxes[:, 3, 1] - boxes[:, 1, 1] + 1)), \
211         "Boxes must have be square, while get heights %s and %s" % \
212         (str(boxes[:, 2, 1] - boxes[:, 0, 1] + 1), str(boxes[:, 3, 1] - boxes[:, 1, 1] + 1))
213     assert len((boxes[:, 1, 0] - boxes[:, 0, 0] + 1).unique()) == 1, \
214         "Boxes can only have one widths, got %s" % str((boxes[:, 1, 0] - boxes[:, 0, 0] + 1).unique())
215     assert len((boxes[:, 2, 1] - boxes[:, 0, 1] + 1).unique()) == 1, \
216         "Boxes can only have one heights, got %s" % str((boxes[:, 2, 1] - boxes[:, 0, 1] + 1).unique())
217 
218     width: torch.Tensor = (boxes[:, 1, 0] - boxes[:, 0, 0] + 1)[0]
219     height: torch.Tensor = (boxes[:, 2, 1] - boxes[:, 0, 1] + 1)[0]
220     return (height, width)
221
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/kornia/geometry/transform/crop.py b/kornia/geometry/transform/crop.py
--- a/kornia/geometry/transform/crop.py
+++ b/kornia/geometry/transform/crop.py
@@ -36,9 +36,9 @@
             ]])
         >>> boxes = torch.tensor([[
                 [1., 1.],
-                [1., 2.],
                 [2., 1.],
                 [2., 2.],
+                [1., 2.],
             ]])  # 1x4x2
         >>> kornia.crop_and_resize(input, boxes, (2, 2))
         tensor([[[ 6.0000,  7.0000],

{"golden_diff": "diff --git a/kornia/geometry/transform/crop.py b/kornia/geometry/transform/crop.py\n--- a/kornia/geometry/transform/crop.py\n+++ b/kornia/geometry/transform/crop.py\n@@ -36,9 +36,9 @@\n             ]])\n         >>> boxes = torch.tensor([[\n                 [1., 1.],\n-                [1., 2.],\n                 [2., 1.],\n                 [2., 2.],\n+                [1., 2.],\n             ]])  # 1x4x2\n         >>> kornia.crop_and_resize(input, boxes, (2, 2))\n         tensor([[[ 6.0000,  7.0000],\n", "issue": "Outdated example\nOutdated example on the geometry.transform.**crop_and_resize**() function\r\n\r\nFollowing the clockwise order for the corners it should be:\r\n\r\n`       >>> boxes = torch.tensor([[\r\n                [1., 1.],\r\n                [1., 2.],\r\n                [2., 2.],\r\n                [2., 1.],\r\n            ]])  # 1x4x2`\r\n\r\nInstead of the current:\r\n`        >>> boxes = torch.tensor([[\r\n                [1., 1.],\r\n                [1., 2.],\r\n                [2., 1.],\r\n                [2., 2.],\r\n            ]])  # 1x4x2`\n", "before_files": [{"content": "from typing import Tuple, Union\n\nimport torch\n\nfrom kornia.geometry.transform.imgwarp import (\n    warp_perspective, get_perspective_transform\n)\n\n__all__ = [\n    \"crop_and_resize\",\n    \"crop_by_boxes\",\n    \"center_crop\",\n]\n\n\ndef crop_and_resize(tensor: torch.Tensor, boxes: torch.Tensor, size: Tuple[int, int],\n                    return_transform: bool = False) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:\n    r\"\"\"Extracts crops from the input tensor and resizes them.\n    Args:\n        tensor (torch.Tensor): the reference tensor of shape BxCxHxW.\n        boxes (torch.Tensor): a tensor containing the coordinates of the\n          bounding boxes to be extracted. The tensor must have the shape\n          of Bx4x2, where each box is defined in the following (clockwise)\n          order: top-left, top-right, bottom-right and bottom-left. The\n          coordinates must be in the x, y order.\n        size (Tuple[int, int]): a tuple with the height and width that will be\n          used to resize the extracted patches.\n    Returns:\n        torch.Tensor: tensor containing the patches with shape BxN1xN2\n    Example:\n        >>> input = torch.tensor([[\n                [1., 2., 3., 4.],\n                [5., 6., 7., 8.],\n                [9., 10., 11., 12.],\n                [13., 14., 15., 16.],\n            ]])\n        >>> boxes = torch.tensor([[\n                [1., 1.],\n                [1., 2.],\n                [2., 1.],\n                [2., 2.],\n            ]])  # 1x4x2\n        >>> kornia.crop_and_resize(input, boxes, (2, 2))\n        tensor([[[ 6.0000,  7.0000],\n                 [ 10.0000, 11.0000]]])\n    \"\"\"\n    if not torch.is_tensor(tensor):\n        raise TypeError(\"Input tensor type is not a torch.Tensor. Got {}\"\n                        .format(type(tensor)))\n    if not torch.is_tensor(boxes):\n        raise TypeError(\"Input boxes type is not a torch.Tensor. Got {}\"\n                        .format(type(boxes)))\n    if not len(tensor.shape) in (3, 4,):\n        raise ValueError(\"Input tensor must be in the shape of CxHxW or \"\n                         \"BxCxHxW. Got {}\".format(tensor.shape))\n    if not isinstance(size, (tuple, list,)) and len(size) == 2:\n        raise ValueError(\"Input size must be a tuple/list of length 2. Got {}\"\n                         .format(size))\n    # unpack input data\n    dst_h: torch.Tensor = torch.tensor(size[0])\n    dst_w: torch.Tensor = torch.tensor(size[1])\n\n    # [x, y] origin\n    # top-left, top-right, bottom-right, bottom-left\n    points_src: torch.Tensor = boxes\n\n    # [x, y] destination\n    # top-left, top-right, bottom-right, bottom-left\n    points_dst: torch.Tensor = torch.tensor([[\n        [0, 0],\n        [dst_w - 1, 0],\n        [dst_w - 1, dst_h - 1],\n        [0, dst_h - 1],\n    ]]).repeat(points_src.shape[0], 1, 1)\n\n    return crop_by_boxes(tensor, points_src, points_dst, return_transform=return_transform)\n\n\ndef center_crop(tensor: torch.Tensor, size: Tuple[int, int],\n                return_transform: bool = False) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:\n    r\"\"\"Crops the given tensor at the center.\n\n    Args:\n        tensor (torch.Tensor): the input tensor with shape (C, H, W) or\n          (B, C, H, W).\n        size (Tuple[int, int]): a tuple with the expected height and width\n          of the output patch.\n\n    Returns:\n        torch.Tensor: the output tensor with patches.\n\n    Examples:\n        >>> input = torch.tensor([[\n                [1., 2., 3., 4.],\n                [5., 6., 7., 8.],\n                [9., 10., 11., 12.],\n                [13., 14., 15., 16.],\n             ]])\n        >>> kornia.center_crop(input, (2, 4))\n        tensor([[[ 5.0000,  6.0000,  7.0000,  8.0000],\n                 [ 9.0000, 10.0000, 11.0000, 12.0000]]])\n    \"\"\"\n    if not torch.is_tensor(tensor):\n        raise TypeError(\"Input tensor type is not a torch.Tensor. Got {}\"\n                        .format(type(tensor)))\n\n    if not len(tensor.shape) in (3, 4,):\n        raise ValueError(\"Input tensor must be in the shape of CxHxW or \"\n                         \"BxCxHxW. Got {}\".format(tensor.shape))\n\n    if not isinstance(size, (tuple, list,)) and len(size) == 2:\n        raise ValueError(\"Input size must be a tuple/list of length 2. Got {}\"\n                         .format(size))\n\n    # unpack input sizes\n    dst_h, dst_w = size\n    src_h, src_w = tensor.shape[-2:]\n\n    # compute start/end offsets\n    dst_h_half = dst_h / 2\n    dst_w_half = dst_w / 2\n    src_h_half = src_h / 2\n    src_w_half = src_w / 2\n\n    start_x = src_w_half - dst_w_half\n    start_y = src_h_half - dst_h_half\n\n    end_x = start_x + dst_w - 1\n    end_y = start_y + dst_h - 1\n    # [y, x] origin\n    # top-left, top-right, bottom-right, bottom-left\n    points_src: torch.Tensor = torch.tensor([[\n        [start_x, start_y],\n        [end_x, start_y],\n        [end_x, end_y],\n        [start_x, end_y],\n    ]])\n\n    # [y, x] destination\n    # top-left, top-right, bottom-right, bottom-left\n    points_dst: torch.Tensor = torch.tensor([[\n        [0, 0],\n        [dst_w - 1, 0],\n        [dst_w - 1, dst_h - 1],\n        [0, dst_h - 1],\n    ]]).repeat(points_src.shape[0], 1, 1)\n    return crop_by_boxes(tensor, points_src, points_dst, return_transform=return_transform)\n\n\ndef crop_by_boxes(tensor, src_box, dst_box,\n                  return_transform: bool = False) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:\n    \"\"\"A wrapper performs crop transform with bounding boxes.\n\n    \"\"\"\n    if tensor.ndimension() not in [3, 4]:\n        raise TypeError(\"Only tensor with shape (C, H, W) and (B, C, H, W) supported. Got %s\" % str(tensor.shape))\n    # warping needs data in the shape of BCHW\n    is_unbatched: bool = tensor.ndimension() == 3\n    if is_unbatched:\n        tensor = torch.unsqueeze(tensor, dim=0)\n\n    # compute transformation between points and warp\n    dst_trans_src: torch.Tensor = get_perspective_transform(\n        src_box.to(tensor.device).to(tensor.dtype),\n        dst_box.to(tensor.device).to(tensor.dtype)\n    )\n    # simulate broadcasting\n    dst_trans_src = dst_trans_src.expand(tensor.shape[0], -1, -1)\n\n    bbox = _infer_bounding_box(dst_box)\n    patches: torch.Tensor = warp_perspective(\n        tensor, dst_trans_src, (int(bbox[0].int().data.item()), int(bbox[1].int().data.item())))\n\n    # return in the original shape\n    if is_unbatched:\n        patches = torch.squeeze(patches, dim=0)\n\n    if return_transform:\n        return patches, dst_trans_src\n\n    return patches\n\n\ndef _infer_bounding_box(boxes: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:\n    r\"\"\"Auto-infer the output sizes.\n\n    Args:\n        boxes (torch.Tensor): a tensor containing the coordinates of the\n          bounding boxes to be extracted. The tensor must have the shape\n          of Bx4x2, where each box is defined in the following (clockwise)\n          order: top-left, top-right, bottom-right, bottom-left. The\n          coordinates must be in the x, y order.\n\n    Returns:\n        (torch.Tensor, torch.Tensor): tensor containing the patches with shape BxN1xN2\n\n    Example:\n        >>> boxes = torch.tensor([[\n                [1., 1.],\n                [2., 1.],\n                [2., 2.],\n                [1., 2.],\n            ]])  # 1x4x2\n        >>> _infer_bounding_box(boxes)\n        (2, 2)\n    \"\"\"\n    assert torch.allclose((boxes[:, 1, 0] - boxes[:, 0, 0] + 1), (boxes[:, 2, 0] - boxes[:, 3, 0] + 1)), \\\n        \"Boxes must have be square, while get widths %s and %s\" % \\\n        (str(boxes[:, 1, 0] - boxes[:, 0, 0] + 1), str(boxes[:, 2, 0] - boxes[:, 3, 0] + 1))\n    assert torch.allclose((boxes[:, 2, 1] - boxes[:, 0, 1] + 1), (boxes[:, 3, 1] - boxes[:, 1, 1] + 1)), \\\n        \"Boxes must have be square, while get heights %s and %s\" % \\\n        (str(boxes[:, 2, 1] - boxes[:, 0, 1] + 1), str(boxes[:, 3, 1] - boxes[:, 1, 1] + 1))\n    assert len((boxes[:, 1, 0] - boxes[:, 0, 0] + 1).unique()) == 1, \\\n        \"Boxes can only have one widths, got %s\" % str((boxes[:, 1, 0] - boxes[:, 0, 0] + 1).unique())\n    assert len((boxes[:, 2, 1] - boxes[:, 0, 1] + 1).unique()) == 1, \\\n        \"Boxes can only have one heights, got %s\" % str((boxes[:, 2, 1] - boxes[:, 0, 1] + 1).unique())\n\n    width: torch.Tensor = (boxes[:, 1, 0] - boxes[:, 0, 0] + 1)[0]\n    height: torch.Tensor = (boxes[:, 2, 1] - boxes[:, 0, 1] + 1)[0]\n    return (height, width)\n", "path": "kornia/geometry/transform/crop.py"}], "after_files": [{"content": "from typing import Tuple, Union\n\nimport torch\n\nfrom kornia.geometry.transform.imgwarp import (\n    warp_perspective, get_perspective_transform\n)\n\n__all__ = [\n    \"crop_and_resize\",\n    \"crop_by_boxes\",\n    \"center_crop\",\n]\n\n\ndef crop_and_resize(tensor: torch.Tensor, boxes: torch.Tensor, size: Tuple[int, int],\n                    return_transform: bool = False) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:\n    r\"\"\"Extracts crops from the input tensor and resizes them.\n    Args:\n        tensor (torch.Tensor): the reference tensor of shape BxCxHxW.\n        boxes (torch.Tensor): a tensor containing the coordinates of the\n          bounding boxes to be extracted. The tensor must have the shape\n          of Bx4x2, where each box is defined in the following (clockwise)\n          order: top-left, top-right, bottom-right and bottom-left. The\n          coordinates must be in the x, y order.\n        size (Tuple[int, int]): a tuple with the height and width that will be\n          used to resize the extracted patches.\n    Returns:\n        torch.Tensor: tensor containing the patches with shape BxN1xN2\n    Example:\n        >>> input = torch.tensor([[\n                [1., 2., 3., 4.],\n                [5., 6., 7., 8.],\n                [9., 10., 11., 12.],\n                [13., 14., 15., 16.],\n            ]])\n        >>> boxes = torch.tensor([[\n                [1., 1.],\n                [2., 1.],\n                [2., 2.],\n                [1., 2.],\n            ]])  # 1x4x2\n        >>> kornia.crop_and_resize(input, boxes, (2, 2))\n        tensor([[[ 6.0000,  7.0000],\n                 [ 10.0000, 11.0000]]])\n    \"\"\"\n    if not torch.is_tensor(tensor):\n        raise TypeError(\"Input tensor type is not a torch.Tensor. Got {}\"\n                        .format(type(tensor)))\n    if not torch.is_tensor(boxes):\n        raise TypeError(\"Input boxes type is not a torch.Tensor. Got {}\"\n                        .format(type(boxes)))\n    if not len(tensor.shape) in (3, 4,):\n        raise ValueError(\"Input tensor must be in the shape of CxHxW or \"\n                         \"BxCxHxW. Got {}\".format(tensor.shape))\n    if not isinstance(size, (tuple, list,)) and len(size) == 2:\n        raise ValueError(\"Input size must be a tuple/list of length 2. Got {}\"\n                         .format(size))\n    # unpack input data\n    dst_h: torch.Tensor = torch.tensor(size[0])\n    dst_w: torch.Tensor = torch.tensor(size[1])\n\n    # [x, y] origin\n    # top-left, top-right, bottom-right, bottom-left\n    points_src: torch.Tensor = boxes\n\n    # [x, y] destination\n    # top-left, top-right, bottom-right, bottom-left\n    points_dst: torch.Tensor = torch.tensor([[\n        [0, 0],\n        [dst_w - 1, 0],\n        [dst_w - 1, dst_h - 1],\n        [0, dst_h - 1],\n    ]]).repeat(points_src.shape[0], 1, 1)\n\n    return crop_by_boxes(tensor, points_src, points_dst, return_transform=return_transform)\n\n\ndef center_crop(tensor: torch.Tensor, size: Tuple[int, int],\n                return_transform: bool = False) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:\n    r\"\"\"Crops the given tensor at the center.\n\n    Args:\n        tensor (torch.Tensor): the input tensor with shape (C, H, W) or\n          (B, C, H, W).\n        size (Tuple[int, int]): a tuple with the expected height and width\n          of the output patch.\n\n    Returns:\n        torch.Tensor: the output tensor with patches.\n\n    Examples:\n        >>> input = torch.tensor([[\n                [1., 2., 3., 4.],\n                [5., 6., 7., 8.],\n                [9., 10., 11., 12.],\n                [13., 14., 15., 16.],\n             ]])\n        >>> kornia.center_crop(input, (2, 4))\n        tensor([[[ 5.0000,  6.0000,  7.0000,  8.0000],\n                 [ 9.0000, 10.0000, 11.0000, 12.0000]]])\n    \"\"\"\n    if not torch.is_tensor(tensor):\n        raise TypeError(\"Input tensor type is not a torch.Tensor. Got {}\"\n                        .format(type(tensor)))\n\n    if not len(tensor.shape) in (3, 4,):\n        raise ValueError(\"Input tensor must be in the shape of CxHxW or \"\n                         \"BxCxHxW. Got {}\".format(tensor.shape))\n\n    if not isinstance(size, (tuple, list,)) and len(size) == 2:\n        raise ValueError(\"Input size must be a tuple/list of length 2. Got {}\"\n                         .format(size))\n\n    # unpack input sizes\n    dst_h, dst_w = size\n    src_h, src_w = tensor.shape[-2:]\n\n    # compute start/end offsets\n    dst_h_half = dst_h / 2\n    dst_w_half = dst_w / 2\n    src_h_half = src_h / 2\n    src_w_half = src_w / 2\n\n    start_x = src_w_half - dst_w_half\n    start_y = src_h_half - dst_h_half\n\n    end_x = start_x + dst_w - 1\n    end_y = start_y + dst_h - 1\n    # [y, x] origin\n    # top-left, top-right, bottom-right, bottom-left\n    points_src: torch.Tensor = torch.tensor([[\n        [start_x, start_y],\n        [end_x, start_y],\n        [end_x, end_y],\n        [start_x, end_y],\n    ]])\n\n    # [y, x] destination\n    # top-left, top-right, bottom-right, bottom-left\n    points_dst: torch.Tensor = torch.tensor([[\n        [0, 0],\n        [dst_w - 1, 0],\n        [dst_w - 1, dst_h - 1],\n        [0, dst_h - 1],\n    ]]).repeat(points_src.shape[0], 1, 1)\n    return crop_by_boxes(tensor, points_src, points_dst, return_transform=return_transform)\n\n\ndef crop_by_boxes(tensor, src_box, dst_box,\n                  return_transform: bool = False) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:\n    \"\"\"A wrapper performs crop transform with bounding boxes.\n\n    \"\"\"\n    if tensor.ndimension() not in [3, 4]:\n        raise TypeError(\"Only tensor with shape (C, H, W) and (B, C, H, W) supported. Got %s\" % str(tensor.shape))\n    # warping needs data in the shape of BCHW\n    is_unbatched: bool = tensor.ndimension() == 3\n    if is_unbatched:\n        tensor = torch.unsqueeze(tensor, dim=0)\n\n    # compute transformation between points and warp\n    dst_trans_src: torch.Tensor = get_perspective_transform(\n        src_box.to(tensor.device).to(tensor.dtype),\n        dst_box.to(tensor.device).to(tensor.dtype)\n    )\n    # simulate broadcasting\n    dst_trans_src = dst_trans_src.expand(tensor.shape[0], -1, -1)\n\n    bbox = _infer_bounding_box(dst_box)\n    patches: torch.Tensor = warp_perspective(\n        tensor, dst_trans_src, (int(bbox[0].int().data.item()), int(bbox[1].int().data.item())))\n\n    # return in the original shape\n    if is_unbatched:\n        patches = torch.squeeze(patches, dim=0)\n\n    if return_transform:\n        return patches, dst_trans_src\n\n    return patches\n\n\ndef _infer_bounding_box(boxes: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:\n    r\"\"\"Auto-infer the output sizes.\n\n    Args:\n        boxes (torch.Tensor): a tensor containing the coordinates of the\n          bounding boxes to be extracted. The tensor must have the shape\n          of Bx4x2, where each box is defined in the following (clockwise)\n          order: top-left, top-right, bottom-right, bottom-left. The\n          coordinates must be in the x, y order.\n\n    Returns:\n        (torch.Tensor, torch.Tensor): tensor containing the patches with shape BxN1xN2\n\n    Example:\n        >>> boxes = torch.tensor([[\n                [1., 1.],\n                [2., 1.],\n                [2., 2.],\n                [1., 2.],\n            ]])  # 1x4x2\n        >>> _infer_bounding_box(boxes)\n        (2, 2)\n    \"\"\"\n    assert torch.allclose((boxes[:, 1, 0] - boxes[:, 0, 0] + 1), (boxes[:, 2, 0] - boxes[:, 3, 0] + 1)), \\\n        \"Boxes must have be square, while get widths %s and %s\" % \\\n        (str(boxes[:, 1, 0] - boxes[:, 0, 0] + 1), str(boxes[:, 2, 0] - boxes[:, 3, 0] + 1))\n    assert torch.allclose((boxes[:, 2, 1] - boxes[:, 0, 1] + 1), (boxes[:, 3, 1] - boxes[:, 1, 1] + 1)), \\\n        \"Boxes must have be square, while get heights %s and %s\" % \\\n        (str(boxes[:, 2, 1] - boxes[:, 0, 1] + 1), str(boxes[:, 3, 1] - boxes[:, 1, 1] + 1))\n    assert len((boxes[:, 1, 0] - boxes[:, 0, 0] + 1).unique()) == 1, \\\n        \"Boxes can only have one widths, got %s\" % str((boxes[:, 1, 0] - boxes[:, 0, 0] + 1).unique())\n    assert len((boxes[:, 2, 1] - boxes[:, 0, 1] + 1).unique()) == 1, \\\n        \"Boxes can only have one heights, got %s\" % str((boxes[:, 2, 1] - boxes[:, 0, 1] + 1).unique())\n\n    width: torch.Tensor = (boxes[:, 1, 0] - boxes[:, 0, 0] + 1)[0]\n    height: torch.Tensor = (boxes[:, 2, 1] - boxes[:, 0, 1] + 1)[0]\n    return (height, width)\n", "path": "kornia/geometry/transform/crop.py"}]}