nvImageCodec with cuPy¶
[1]:
import os
import cv2
import cupy as cp
from matplotlib import pyplot as plt
Setting resource folder
[2]:
resources_dir = os.getenv("PYNVIMGCODEC_EXAMPLES_RESOURCES_DIR", "../assets/images/")
Import nvImageCodec module and create both Decoder and Encoder
[3]:
from nvidia import nvimgcodec
decoder = nvimgcodec.Decoder()
encoder = nvimgcodec.Encoder()
Load jpeg2000 image with nvImageCodec
[4]:
nv_img = decoder.read(resources_dir + "cat-1046544_640.jp2")
print(nv_img.__cuda_array_interface__)
{'shape': (475, 640, 3), 'strides': None, 'typestr': '|u1', 'data': (12918456320, False), 'version': 3, 'stream': 1}
Pass nvImageCodec Image to cupy asarray as it accepts __cuda_array_interface__
[5]:
%%time
cp_img = cp.asarray(nv_img)
print(cp_img.__cuda_array_interface__)
{'shape': (475, 640, 3), 'typestr': '|u1', 'descr': [('', '|u1')], 'stream': 1, 'version': 3, 'strides': None, 'data': (12918456320, False)}
CPU times: user 0 ns, sys: 2.3 ms, total: 2.3 ms
Wall time: 2.12 ms
Convert to numpy and show
[6]:
np_img4k = cp.asnumpy(cp_img)
plt.imshow(np_img4k)
[6]:
<matplotlib.image.AxesImage at 0x7f892d1e8fd0>
![../_images/samples_cupy_sample_11_1.png](../_images/samples_cupy_sample_11_1.png)
Lets do some opration on image in GPU using cupyx.scipy
[7]:
import cupyx.scipy.ndimage
[8]:
cp_img_rotated = cupyx.scipy.ndimage.rotate(cp_img, 90)
cp_img_gaussian = cupyx.scipy.ndimage.gaussian_filter(cp_img, sigma = 5)
print(cp_img_rotated.__cuda_array_interface__)
{'shape': (640, 475, 3), 'typestr': '|u1', 'descr': [('', '|u1')], 'stream': 1, 'version': 3, 'strides': None, 'data': (140226985584640, False)}
[9]:
np_img = cp.asnumpy(cp_img_rotated)
plt.imshow(np_img)
[9]:
<matplotlib.image.AxesImage at 0x7f892c0e1e80>
![../_images/samples_cupy_sample_15_1.png](../_images/samples_cupy_sample_15_1.png)
[10]:
np_img = cp.asnumpy(cp_img_gaussian)
plt.imshow(np_img)
[10]:
<matplotlib.image.AxesImage at 0x7f892c0723a0>
![../_images/samples_cupy_sample_16_1.png](../_images/samples_cupy_sample_16_1.png)
Convert cupy Image to nvImageCodec Image using __cuda_array_interface__
[11]:
%%time
nv_rotated_img = nvimgcodec.as_image(cp_img_rotated)
CPU times: user 53 µs, sys: 35 µs, total: 88 µs
Wall time: 93.2 µs
Check content
[12]:
plt.imshow(nv_rotated_img.cpu())
[12]:
<matplotlib.image.AxesImage at 0x7f890ae8a550>
![../_images/samples_cupy_sample_20_1.png](../_images/samples_cupy_sample_20_1.png)
Save as Jpeg2000
[13]:
encoder.write("rotated.j2k", nv_rotated_img)
Load with OpenCv to verify
[14]:
image = cv2.imread("rotated.j2k")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.imshow(image)
[14]:
<matplotlib.image.AxesImage at 0x7f890adebdf0>
![../_images/samples_cupy_sample_24_1.png](../_images/samples_cupy_sample_24_1.png)
Save cupy image to jpg with nvImageCodec
[15]:
nv_img_gaussian = nvimgcodec.as_image(cp_img_gaussian)
encoder.write("gaussian.jpg", nv_img_gaussian)
Read back with OpenCV to verify
[16]:
image = cv2.imread("gaussian.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.imshow(image)
[16]:
<matplotlib.image.AxesImage at 0x7f89085714f0>
![../_images/samples_cupy_sample_28_1.png](../_images/samples_cupy_sample_28_1.png)
DLPack¶
Passing cuPy ndarray to nvImageCodec using DLPack. cuPy ndarray has both cuda_array_interface and dlpack interface. By default, cuda_array_interface is preferred and will be used when we pass cuPy ndarray to nvImageCodec using as_image function. If we would like to use DLPack, firstly PyCapsule need to be taken from cuPy ndarray and then it needs to be passed to nvImageCodec.
[17]:
dlpack_img = cp_img_gaussian.toDlpack()
nv_img_gaussian = nvimgcodec.as_image(dlpack_img)
encoder.write("gaussian_dlpack.jpg", nv_img_gaussian)
[18]:
image = cv2.imread("gaussian_dlpack.jpg")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.imshow(image)
[18]:
<matplotlib.image.AxesImage at 0x7f89084e86a0>
![../_images/samples_cupy_sample_32_1.png](../_images/samples_cupy_sample_32_1.png)
Passing nvImageCodec Image to cuPy using DLPack
[19]:
nv_img = decoder.read(resources_dir + "cat-1046544_640.jp2")
cp_img = cp.from_dlpack(nv_img)
[20]:
np_img = cp.asnumpy(cp_img)
plt.imshow(np_img)
[20]:
<matplotlib.image.AxesImage at 0x7f890845e820>
![../_images/samples_cupy_sample_35_1.png](../_images/samples_cupy_sample_35_1.png)
Alternatively, there is possibility to firstly take PyCapsule and then pass it to cuPy
[21]:
nv_img = decoder.read(resources_dir + "cat-1046544_640.jp2")
py_cap = nv_img.__dlpack__()
cp_img = cp.from_dlpack(py_cap)
[22]:
np_img = cp.asnumpy(cp_img)
plt.imshow(np_img4k)
[22]:
<matplotlib.image.AxesImage at 0x7f890844f640>
![../_images/samples_cupy_sample_38_1.png](../_images/samples_cupy_sample_38_1.png)