We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`to_image` does not handle numpy 2D arrays
### 🐛 Describe the bug

[`to_image`](https://github.com/pytorch/vision/blob/806dba678d5b01f6e8a46f7c48fdf8c09369a267/torchvision/transforms/v2/functional/_type_conversion.py#L11) should be able to handle [numpy arrays](https://numpy.org/doc/stable/reference/generated/numpy.array.html) with shape `(H, W)`. This corresponds to the previous behavior of [`to_tensor`](https://github.com/pytorch/vision/blob/806dba678d5b01f6e8a46f7c48fdf8c09369a267/torchvision/transforms/functional.py#L149). Running the following:


```python
import numpy as np
from torchvision.transforms.v2.functional import to_image

img_npy = np.random.randint(0, 256, (224, 224), dtype=np.uint8)
to_image(img_npy)
```

results in error:

```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/mantasu/programs/anaconda/envs/glasses-detector-312/lib/python3.12/site-packages/torchvision/transforms/v2/functional/_type_conversion.py", line 14, in to_image
    output = torch.from_numpy(inpt).permute((2, 0, 1)).contiguous()
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: permute(sparse_coo): number of dimensions in the tensor input does not match the length of the desired ordering of dimensions i.e. input.dim() = 2 is not equal to len(dims) = 3
```


PIL grayscale images are handled correctly:
```python
from PIL import Image

img_pil = Image.fromarray(img_npy)
print(to_image(img_pil).shape) # (1, 224, 224)
```



### Versions

```
PyTorch version: 2.2.0
Is debug build: False
CUDA used to build PyTorch: 12.1
ROCM used to build PyTorch: N/A

OS: Ubuntu 22.04.3 LTS (x86_64)
GCC version: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Clang version: Could not collect
CMake version: Could not collect
Libc version: glibc-2.35

Python version: 3.11.7 | packaged by conda-forge | (main, Dec 23 2023, 14:43:09) [GCC 12.3.0] (64-bit runtime)
Python platform: Linux-5.15.133.1-microsoft-standard-WSL2-x86_64-with-glibc2.35
Is CUDA available: True
CUDA runtime version: Could not collect
CUDA_MODULE_LOADING set to: LAZY
GPU models and configuration: GPU 0: NVIDIA GeForce RTX 3080 Ti Laptop GPU
Nvidia driver version: 546.33
cuDNN version: Probably one of the following:
/usr/lib/x86_64-linux-gnu/libcudnn.so.8.9.7
/usr/lib/x86_64-linux-gnu/libcudnn_adv_infer.so.8.9.7
/usr/lib/x86_64-linux-gnu/libcudnn_adv_train.so.8.9.7
/usr/lib/x86_64-linux-gnu/libcudnn_cnn_infer.so.8.9.7
/usr/lib/x86_64-linux-gnu/libcudnn_cnn_train.so.8.9.7
/usr/lib/x86_64-linux-gnu/libcudnn_ops_infer.so.8.9.7
/usr/lib/x86_64-linux-gnu/libcudnn_ops_train.so.8.9.7
HIP runtime version: N/A
MIOpen runtime version: N/A
Is XNNPACK available: True

CPU:
Architecture:                       x86_64
CPU op-mode(s):                     32-bit, 64-bit
Address sizes:                      39 bits physical, 48 bits virtual
Byte Order:                         Little Endian
CPU(s):                             24
On-line CPU(s) list:                0-23
Vendor ID:                          GenuineIntel
Model name:                         12th Gen Intel(R) Core(TM) i7-12800HX
CPU family:                         6
Model:                              151
Thread(s) per core:                 2
Core(s) per socket:                 12
Socket(s):                          1
Stepping:                           2
BogoMIPS:                           4607.99
Flags:                              fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology tsc_reliable nonstop_tsc cpuid pni pclmulqdq vmx ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves avx_vnni umip waitpkg gfni vaes vpclmulqdq rdpid movdiri movdir64b fsrm serialize flush_l1d arch_capabilities
Virtualization:                     VT-x
Hypervisor vendor:                  Microsoft
Virtualization type:                full
L1d cache:                          576 KiB (12 instances)
L1i cache:                          384 KiB (12 instances)
L2 cache:                           15 MiB (12 instances)
L3 cache:                           25 MiB (1 instance)
Vulnerability Gather data sampling: Not affected
Vulnerability Itlb multihit:        Not affected
Vulnerability L1tf:                 Not affected
Vulnerability Mds:                  Not affected
Vulnerability Meltdown:             Not affected
Vulnerability Mmio stale data:      Not affected
Vulnerability Retbleed:             Mitigation; Enhanced IBRS
Vulnerability Spec rstack overflow: Not affected
Vulnerability Spec store bypass:    Mitigation; Speculative Store Bypass disabled via prctl and seccomp
Vulnerability Spectre v1:           Mitigation; usercopy/swapgs barriers and __user pointer sanitization
Vulnerability Spectre v2:           Mitigation; Enhanced IBRS, IBPB conditional, RSB filling, PBRSB-eIBRS SW sequence
Vulnerability Srbds:                Not affected
Vulnerability Tsx async abort:      Not affected

Versions of relevant libraries:
[pip3] numpy==1.26.3
[pip3] torch==2.2.0
[pip3] torchaudio==2.2.0
[pip3] torchvision==0.17.0
[pip3] triton==2.2.0
[conda] blas                      1.0                         mkl    conda-forge
[conda] ffmpeg                    4.3                  hf484d3e_0    pytorch
[conda] libjpeg-turbo             2.0.0                h9bf148f_0    pytorch
[conda] mkl                       2023.1.0         h213fc3f_46344  
[conda] numpy                     1.26.3          py311h64a7726_0    conda-forge
[conda] pytorch                   2.2.0           py3.11_cuda12.1_cudnn8.9.2_0    pytorch
[conda] pytorch-cuda              12.1                 ha16c6d3_5    pytorch
[conda] pytorch-mutex             1.0                        cuda    pytorch
[conda] torchaudio                2.2.0               py311_cu121    pytorch
[conda] torchtriton               2.2.0                     py311    pytorch
[conda] torchvision               0.17.0              py311_cu121    pytorch
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `torchvision/transforms/v2/functional/_type_conversion.py`
Content:
```
1 from typing import Union
2 
3 import numpy as np
4 import PIL.Image
5 import torch
6 from torchvision import tv_tensors
7 from torchvision.transforms import functional as _F
8 
9 
10 @torch.jit.unused
11 def to_image(inpt: Union[torch.Tensor, PIL.Image.Image, np.ndarray]) -> tv_tensors.Image:
12     """See :class:`~torchvision.transforms.v2.ToImage` for details."""
13     if isinstance(inpt, np.ndarray):
14         output = torch.from_numpy(inpt).permute((2, 0, 1)).contiguous()
15     elif isinstance(inpt, PIL.Image.Image):
16         output = pil_to_tensor(inpt)
17     elif isinstance(inpt, torch.Tensor):
18         output = inpt
19     else:
20         raise TypeError(
21             f"Input can either be a pure Tensor, a numpy array, or a PIL image, but got {type(inpt)} instead."
22         )
23     return tv_tensors.Image(output)
24 
25 
26 to_pil_image = _F.to_pil_image
27 pil_to_tensor = _F.pil_to_tensor
28
```
--- 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/torchvision/transforms/v2/functional/_type_conversion.py b/torchvision/transforms/v2/functional/_type_conversion.py
--- a/torchvision/transforms/v2/functional/_type_conversion.py
+++ b/torchvision/transforms/v2/functional/_type_conversion.py
@@ -11,7 +11,7 @@
 def to_image(inpt: Union[torch.Tensor, PIL.Image.Image, np.ndarray]) -> tv_tensors.Image:
     """See :class:`~torchvision.transforms.v2.ToImage` for details."""
     if isinstance(inpt, np.ndarray):
-        output = torch.from_numpy(inpt).permute((2, 0, 1)).contiguous()
+        output = torch.from_numpy(np.atleast_3d(inpt)).permute((2, 0, 1)).contiguous()
     elif isinstance(inpt, PIL.Image.Image):
         output = pil_to_tensor(inpt)
     elif isinstance(inpt, torch.Tensor):

{"golden_diff": "diff --git a/torchvision/transforms/v2/functional/_type_conversion.py b/torchvision/transforms/v2/functional/_type_conversion.py\n--- a/torchvision/transforms/v2/functional/_type_conversion.py\n+++ b/torchvision/transforms/v2/functional/_type_conversion.py\n@@ -11,7 +11,7 @@\n def to_image(inpt: Union[torch.Tensor, PIL.Image.Image, np.ndarray]) -> tv_tensors.Image:\n     \"\"\"See :class:`~torchvision.transforms.v2.ToImage` for details.\"\"\"\n     if isinstance(inpt, np.ndarray):\n-        output = torch.from_numpy(inpt).permute((2, 0, 1)).contiguous()\n+        output = torch.from_numpy(np.atleast_3d(inpt)).permute((2, 0, 1)).contiguous()\n     elif isinstance(inpt, PIL.Image.Image):\n         output = pil_to_tensor(inpt)\n     elif isinstance(inpt, torch.Tensor):\n", "issue": "`to_image` does not handle numpy 2D arrays\n### \ud83d\udc1b Describe the bug\r\n\r\n[`to_image`](https://github.com/pytorch/vision/blob/806dba678d5b01f6e8a46f7c48fdf8c09369a267/torchvision/transforms/v2/functional/_type_conversion.py#L11) should be able to handle [numpy arrays](https://numpy.org/doc/stable/reference/generated/numpy.array.html) with shape `(H, W)`. This corresponds to the previous behavior of [`to_tensor`](https://github.com/pytorch/vision/blob/806dba678d5b01f6e8a46f7c48fdf8c09369a267/torchvision/transforms/functional.py#L149). Running the following:\r\n\r\n\r\n```python\r\nimport numpy as np\r\nfrom torchvision.transforms.v2.functional import to_image\r\n\r\nimg_npy = np.random.randint(0, 256, (224, 224), dtype=np.uint8)\r\nto_image(img_npy)\r\n```\r\n\r\nresults in error:\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"<stdin>\", line 1, in <module>\r\n  File \"/home/mantasu/programs/anaconda/envs/glasses-detector-312/lib/python3.12/site-packages/torchvision/transforms/v2/functional/_type_conversion.py\", line 14, in to_image\r\n    output = torch.from_numpy(inpt).permute((2, 0, 1)).contiguous()\r\n             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\nRuntimeError: permute(sparse_coo): number of dimensions in the tensor input does not match the length of the desired ordering of dimensions i.e. input.dim() = 2 is not equal to len(dims) = 3\r\n```\r\n\r\n\r\nPIL grayscale images are handled correctly:\r\n```python\r\nfrom PIL import Image\r\n\r\nimg_pil = Image.fromarray(img_npy)\r\nprint(to_image(img_pil).shape) # (1, 224, 224)\r\n```\r\n\r\n\r\n\r\n### Versions\r\n\r\n```\r\nPyTorch version: 2.2.0\r\nIs debug build: False\r\nCUDA used to build PyTorch: 12.1\r\nROCM used to build PyTorch: N/A\r\n\r\nOS: Ubuntu 22.04.3 LTS (x86_64)\r\nGCC version: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0\r\nClang version: Could not collect\r\nCMake version: Could not collect\r\nLibc version: glibc-2.35\r\n\r\nPython version: 3.11.7 | packaged by conda-forge | (main, Dec 23 2023, 14:43:09) [GCC 12.3.0] (64-bit runtime)\r\nPython platform: Linux-5.15.133.1-microsoft-standard-WSL2-x86_64-with-glibc2.35\r\nIs CUDA available: True\r\nCUDA runtime version: Could not collect\r\nCUDA_MODULE_LOADING set to: LAZY\r\nGPU models and configuration: GPU 0: NVIDIA GeForce RTX 3080 Ti Laptop GPU\r\nNvidia driver version: 546.33\r\ncuDNN version: Probably one of the following:\r\n/usr/lib/x86_64-linux-gnu/libcudnn.so.8.9.7\r\n/usr/lib/x86_64-linux-gnu/libcudnn_adv_infer.so.8.9.7\r\n/usr/lib/x86_64-linux-gnu/libcudnn_adv_train.so.8.9.7\r\n/usr/lib/x86_64-linux-gnu/libcudnn_cnn_infer.so.8.9.7\r\n/usr/lib/x86_64-linux-gnu/libcudnn_cnn_train.so.8.9.7\r\n/usr/lib/x86_64-linux-gnu/libcudnn_ops_infer.so.8.9.7\r\n/usr/lib/x86_64-linux-gnu/libcudnn_ops_train.so.8.9.7\r\nHIP runtime version: N/A\r\nMIOpen runtime version: N/A\r\nIs XNNPACK available: True\r\n\r\nCPU:\r\nArchitecture:                       x86_64\r\nCPU op-mode(s):                     32-bit, 64-bit\r\nAddress sizes:                      39 bits physical, 48 bits virtual\r\nByte Order:                         Little Endian\r\nCPU(s):                             24\r\nOn-line CPU(s) list:                0-23\r\nVendor ID:                          GenuineIntel\r\nModel name:                         12th Gen Intel(R) Core(TM) i7-12800HX\r\nCPU family:                         6\r\nModel:                              151\r\nThread(s) per core:                 2\r\nCore(s) per socket:                 12\r\nSocket(s):                          1\r\nStepping:                           2\r\nBogoMIPS:                           4607.99\r\nFlags:                              fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology tsc_reliable nonstop_tsc cpuid pni pclmulqdq vmx ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch ssbd ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves avx_vnni umip waitpkg gfni vaes vpclmulqdq rdpid movdiri movdir64b fsrm serialize flush_l1d arch_capabilities\r\nVirtualization:                     VT-x\r\nHypervisor vendor:                  Microsoft\r\nVirtualization type:                full\r\nL1d cache:                          576 KiB (12 instances)\r\nL1i cache:                          384 KiB (12 instances)\r\nL2 cache:                           15 MiB (12 instances)\r\nL3 cache:                           25 MiB (1 instance)\r\nVulnerability Gather data sampling: Not affected\r\nVulnerability Itlb multihit:        Not affected\r\nVulnerability L1tf:                 Not affected\r\nVulnerability Mds:                  Not affected\r\nVulnerability Meltdown:             Not affected\r\nVulnerability Mmio stale data:      Not affected\r\nVulnerability Retbleed:             Mitigation; Enhanced IBRS\r\nVulnerability Spec rstack overflow: Not affected\r\nVulnerability Spec store bypass:    Mitigation; Speculative Store Bypass disabled via prctl and seccomp\r\nVulnerability Spectre v1:           Mitigation; usercopy/swapgs barriers and __user pointer sanitization\r\nVulnerability Spectre v2:           Mitigation; Enhanced IBRS, IBPB conditional, RSB filling, PBRSB-eIBRS SW sequence\r\nVulnerability Srbds:                Not affected\r\nVulnerability Tsx async abort:      Not affected\r\n\r\nVersions of relevant libraries:\r\n[pip3] numpy==1.26.3\r\n[pip3] torch==2.2.0\r\n[pip3] torchaudio==2.2.0\r\n[pip3] torchvision==0.17.0\r\n[pip3] triton==2.2.0\r\n[conda] blas                      1.0                         mkl    conda-forge\r\n[conda] ffmpeg                    4.3                  hf484d3e_0    pytorch\r\n[conda] libjpeg-turbo             2.0.0                h9bf148f_0    pytorch\r\n[conda] mkl                       2023.1.0         h213fc3f_46344  \r\n[conda] numpy                     1.26.3          py311h64a7726_0    conda-forge\r\n[conda] pytorch                   2.2.0           py3.11_cuda12.1_cudnn8.9.2_0    pytorch\r\n[conda] pytorch-cuda              12.1                 ha16c6d3_5    pytorch\r\n[conda] pytorch-mutex             1.0                        cuda    pytorch\r\n[conda] torchaudio                2.2.0               py311_cu121    pytorch\r\n[conda] torchtriton               2.2.0                     py311    pytorch\r\n[conda] torchvision               0.17.0              py311_cu121    pytorch\r\n```\n", "before_files": [{"content": "from typing import Union\n\nimport numpy as np\nimport PIL.Image\nimport torch\nfrom torchvision import tv_tensors\nfrom torchvision.transforms import functional as _F\n\n\n@torch.jit.unused\ndef to_image(inpt: Union[torch.Tensor, PIL.Image.Image, np.ndarray]) -> tv_tensors.Image:\n    \"\"\"See :class:`~torchvision.transforms.v2.ToImage` for details.\"\"\"\n    if isinstance(inpt, np.ndarray):\n        output = torch.from_numpy(inpt).permute((2, 0, 1)).contiguous()\n    elif isinstance(inpt, PIL.Image.Image):\n        output = pil_to_tensor(inpt)\n    elif isinstance(inpt, torch.Tensor):\n        output = inpt\n    else:\n        raise TypeError(\n            f\"Input can either be a pure Tensor, a numpy array, or a PIL image, but got {type(inpt)} instead.\"\n        )\n    return tv_tensors.Image(output)\n\n\nto_pil_image = _F.to_pil_image\npil_to_tensor = _F.pil_to_tensor\n", "path": "torchvision/transforms/v2/functional/_type_conversion.py"}], "after_files": [{"content": "from typing import Union\n\nimport numpy as np\nimport PIL.Image\nimport torch\nfrom torchvision import tv_tensors\nfrom torchvision.transforms import functional as _F\n\n\n@torch.jit.unused\ndef to_image(inpt: Union[torch.Tensor, PIL.Image.Image, np.ndarray]) -> tv_tensors.Image:\n    \"\"\"See :class:`~torchvision.transforms.v2.ToImage` for details.\"\"\"\n    if isinstance(inpt, np.ndarray):\n        output = torch.from_numpy(np.atleast_3d(inpt)).permute((2, 0, 1)).contiguous()\n    elif isinstance(inpt, PIL.Image.Image):\n        output = pil_to_tensor(inpt)\n    elif isinstance(inpt, torch.Tensor):\n        output = inpt\n    else:\n        raise TypeError(\n            f\"Input can either be a pure Tensor, a numpy array, or a PIL image, but got {type(inpt)} instead.\"\n        )\n    return tv_tensors.Image(output)\n\n\nto_pil_image = _F.to_pil_image\npil_to_tensor = _F.pil_to_tensor\n", "path": "torchvision/transforms/v2/functional/_type_conversion.py"}]}