The basis of PIL library

When torchVision.transforms is used, the Image type typically used for the data enhancement is pil.image. Therefore, if you use imageio or SkImage library to read an image of type NP. ndarray, you need to convert it. This section is to make a simple summary of PIL library.

Basic information about the Image

Shape and type

The common module in PIL library is the Image module. There are two ways to read images: image.open () or image.fromarray ().

img = imageio.imread("0.jpg")
img1 = Image.fromarray(img)

img2 = Image.open("0.jpg")
Copy the code

The type of img1 or img2 is

, not NP.array. The shape is HWC. Data enhancements in TorchVision.transforms use PIL images by default, so if nP.ndarray is read in, they need to be converted to pil.image.

attribute

image = Image.open("0.jpg")
print('width: ', image.width)
print('height: ', image.height)
print('size: ', image.size)
print('mode: ', image.mode)
print('format: ', image.format)
print('category: ', image.category)
print('readonly: ', image.readonly)
print('info: ', image.info)

#output
width:  320
height:  223
size:  (320.223)
mode:  RGB
format:  JPEG
category:  0
readonly:  1
info:  {'jfif': 257.'jfif_version': (1.1), 'dpi': (72.72), 'jfif_unit': 1.'jfif_density': (72.72)}
Copy the code

The data format

The data stored in PIL is stored in the format of Uint8, which represents eight-bit unsigned numbers ranging from 0 to 255. If this format condition is not met during conversion, an error is reported.

PIL library basic function operations

To add…

PIL and NUMpy convert to each other

Why conversion is needed

Libraries commonly used to read images include Imageio and Skimage, as well as CV2, whose data types are shown below. Because torchVision.Transforms used PIL as the default image processing library, we needed to transform NP.ndarray to PIL processing. Pil. Image and Np. ndarray can be converted to each other. Shape remains HWC during conversion.

img_ski = io.imread("0.jpg")
img_cv2 = cv2.imread("0.jpg")
img_imgIO = imageio.imread("0.jpg")

print(type(img_ski))
print(type(img_cv2))
print(type(img_imgIO))

#output:
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
<class 'imageio.core.util.Array'>
Copy the code

Note:imageio.core.util.ArrayType, which is a subtype of Np.darray. 【 stackoverflow 】

imageio.core.util.Array is a subclass of the NumPy array, so it is correct to say that imread returns a NumPy array. You can find the source code for Array at Github.com/imageio/ima… .

Image and NP.ndarray conversion

The Image converted to np. Ndarray

image = Image.open("0.jpg")
img = np.array(image)
print(img.shape)

#output:
(223, 320, 3)
Copy the code

Np. Ndarray into the Image

img = imageio.imread("0.jpg")
img1 = Image.fromarray(img)
img1.show()
Copy the code

Type error:

img = np.ones((448.448.3))
print(img.dtype)
img1 = Image.fromarray(img)

# the output:
float64
Copy the code
TypeError: Cannot handle this data type: (1.1.3), <f8
Copy the code

As you can see from the above output, IMG has a data type of FLOAT64, while PIL needs a data type of Uint8, so an error is reported. The modification mode is:

img = np.ones((448.448.3))
print(img.dtype)
img2 = Image.fromarray(np.uint8(img))
Copy the code

PIL and transforms

Transforms is a data enhancement library in Torch. Common libraries for PIL are ToPILImage and ToTensor.

ToPILImage

The need for ToPILImage is to translate Np. ndarray or tensor into Pil. Image, where you do a channel conversion, and then HWC.

Npimg = PIC if isinstance(PIC, torch.FloatTensor) and mode! = 'F': pic = pic.mul(255).byte() if isinstance(pic, torch.Tensor): npimg = np.transpose(pic.numpy(), (1, 2, 0))Copy the code

ToTensor

The tensor default is CHW. This has already been done at ToTensor(), so you don’t need to do anything else.

But at show you have a tensor shape of CHW, and then you need HWC in Matplotlib so you have to translate it back.

def to_tensor(pic) :
    """Convert a ``PIL Image`` or ``numpy.ndarray`` to tensor. Args: pic (PIL Image or numpy.ndarray): Image to be converted to tensor. Returns: Tensor: Converted image. """.# ---------# handle numpy array------------
    if isinstance(pic, np.ndarray):
        if pic.ndim == 2:
            pic = pic[:, :, None]

        img = torch.from_numpy(pic.transpose((2.0.1))) This is the transformation
        # backward compatibility
        if isinstance(img, torch.ByteTensor):
            return img.float().div(255)
        else:
            return img
    ......

    # -----------handle PIL Image----------------
    Here you can see that the conversion from PIL to Torch at tensor was done through nP.array.
    if pic.mode == 'I':
        img = torch.from_numpy(np.array(pic, np.int32, copy=False))
    elif pic.mode == 'I; 16 ':
        img = torch.from_numpy(np.array(pic, np.int16, copy=False))
    elif pic.mode == 'F':
        img = torch.from_numpy(np.array(pic, np.float32, copy=False))
    elif pic.mode == '1':
        img = 255 * torch.from_numpy(np.array(pic, np.uint8, copy=False))
    else:
        img = torch.ByteTensor(torch.ByteStorage.from_buffer(pic.tobytes()))

    img = img.view(pic.size[1], pic.size[0].len(pic.getbands()))
    # put it from HWC to CHW format
    img = img.permute((2.0.1)).contiguous()  # Here is the conversion
    if isinstance(img, torch.ByteTensor):
        return img.float().div(255)
    else:
        return img
Copy the code

Summary: This time recorded three aspects of content, respectively PIL base content, PIL and NP.nDARray transformation, PIL in the transforms of the two classes. PIL reads data with basic information, such as shape as HWC, data type as Uint8, and some basic attributes. When reading data, the read type is usually NP.ndarray, so the pil. Image Image needs to be converted. Transforms transforms ToPILImage, which transforms NP. ndarray or tensor into PIL, where it changes the channel to HWC, and ToTensor, which transforms PIL into tensor and changes the channel at the same time.

Collection of links

Zodiac Wang (Zodiac911.github. IO)

The difference between different functions in Python that read image formats _u013044310 blog-csdn blog_img. astype

Convert Numpy, Opencv and pil. Image formats to each other _Onwaier blog -CSDN blog _numpy to Opencv

Pytorch: On numpy and PIL conversion issues _ Ryuki Sakura’s blog -CSDN blog