Can not use save_image to save image after data augmentation

Jaturong: <p>I’m beginner for Pytorch. I want to increase the number of datasets (data augmentation).<br>
In this case, I have one image of cat and I want to use <code>albumentations</code> to increase the number of images and save image into another folder as follows:</p>
<pre><code class="lang-auto">import cv2
import torch
import albumentations as A
import numpy as np
import matplotlib.pyplot as plt
from torchvision.utils import save_image
</code></pre>
<p>I define an augmentation as follows:</p>
<pre><code class="lang-auto">LOADER_TRANSFORMED = A.Compose([
    A.HorizontalFlip(p=0.6),
    A.RandomBrightnessContrast(brightness_limit=1, contrast_limit=1, p=0.4)
])
</code></pre>
<p>I use <code>OpenCV </code> to read an image and convert it to the RGB colorspace.</p>
<pre><code class="lang-auto">IMAGE = cv2.imread('/content/drive/MyDrive/Test/cat.jpg') # default BGR
IMAGE = cv2.cvtColor(IMAGE, cv2.COLOR_BGR2RGB) # BGR -&gt; RGB
</code></pre>
<p>Augment an image as follows:</p>
<pre><code class="lang-auto">TRANSFORMED = LOADER_TRANSFORMED(image=IMAGE) # dict
TRANSFORMED_IMAGE = TRANSFORMED["image"] # numpy.ndarray
</code></pre>
<pre><code class="lang-auto">TRANSFORMED_IMAGE_2 = LOADER_TRANSFORMED(image=IMAGE)["image"]
</code></pre>
<p>In this part, I want to save image after augmentation using <code>save_image</code> as follows: <br><br>
<strong>step 1:</strong> convert <code>numpy</code> to <code>tensor</code></p>
<pre><code class="lang-auto">TRAN_IMG_2 = torch.from_numpy(TRANSFORMED_IMAGE_2)
</code></pre>
<p><strong>step 2:</strong> <code>save_image</code></p>
<pre><code class="lang-auto">save_image(TRAN_IMG_2, '/content/drive/MyDrive/Test/Aug_cat')
</code></pre>
<p>I got the error as follows:</p>
<blockquote>
<p>RuntimeError: result type Float can’t be cast to the desired output type Byte</p>
</blockquote>
<p><strong>I’m not sure, Where did the error occur?</strong> because in <a href="https://pytorch.org/vision/main/generated/torchvision.utils.save_image.html" rel="noopener nofollow ugc">save_image</a> require tensor as input.</p>

andrea.tantucci: <p><a class="mention" href="/u/jaturong">@Jaturong</a> maybe you need to specify the format of the image, like this</p>
<pre><code class="lang-auto">save_image(TRAN_IMG_2, '/content/drive/MyDrive/Test/Aug_cat.jpg')
</code></pre>

Jaturong: <p><a class="mention" href="/u/andrea.tantucci">@andrea.tantucci</a> I have tried your method. But still got the same result.</p>

ptrblck: <p>Could you post the <code>dtype</code> of <code>TRAN_IMG_2</code> as well as its min and max values and shape, please?</p>

Jaturong: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> I got the <code>dtype</code> of <code>TRAN_IMG_2</code> is <code>&lt;class 'torch.Tensor'&gt;</code>.<br>
<strong>Min and Max values</strong> are <code>tensor(93, dtype=torch.uint8)</code> and <code>tensor(255, dtype=torch.uint8)</code> respectively.<br>
And <strong>shape of tensor</strong> is <code>torch.Size([666, 1000, 3])</code></p>

ptrblck: <p>Thank you for this information!<br>
The docs seem to lack the information that normalized floating point tensors are expected, since internally the inputs will be “unnormalized” and cast to <code>uitn8</code> as seen <a href="https://github.com/pytorch/vision/blob/6c4ff94b56a8a26c150af0cd95f37bf30e1b8eb4/torchvision/utils.py#L149">here</a>.</p>
<p>Additionally, the channels-first memory layout is expected. This code should work:</p>
<pre><code class="lang-python">x = torch.randint(93, 256, (666, 1000, 3)).to(torch.uint8)
print(x.shape)
# torch.Size([666, 1000, 3])
print(x.min(), x.max())
# tensor(93, dtype=torch.uint8) tensor(255, dtype=torch.uint8)

save_image(x, "tmp.jpeg")
# RuntimeError: result type Float can't be cast to the desired output type Byte

# normalize
y = x.float() / 255.
print(y.min(), y.max())
# tensor(0.3647) tensor(1.)

# wrong memory layout
save_image(y, "tmp.jpeg")
# TypeError: Cannot handle this data type: (1, 1, 666), |u1

y = y.permute(2, 0, 1)
save_image(y, "tmp.jpeg")
</code></pre>

Jaturong: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> Thank you very much. I can save image using above code.</p>