show_image(image_r, 'gray')zeros = np.zeros((5,5), dtype=np.uint8)stacked_red = np.zeros((5,5,3), dtype=np.uint8) # the format is HxWxX (height X width X channel)stacked_red[:,:,0] = image_r # also same thing can be achieved stacked_red = np.stack([image_r, zeros, zeros], axis=2)show_image(stacked_red)
Code
def image_channels(red, green, blue, rgb, gray, rows=(0, 1, 2)): fig, axs = plt.subplots(len(rows), 4, figsize=(15, 5.5)) zeros = np.zeros((5, 5), dtype=np.uint8) titles1 = ['Red', 'Green', 'Blue', 'Grayscale Image'] titles0 = ['image_r', 'image_g', 'image_b', 'image_gray'] titles2 = ['as first channel', 'as second channel', 'as third channel', 'RGB Image'] idx0 = np.argmax(np.array(rows) ==0) idx1 = np.argmax(np.array(rows) ==1) idx2 = np.argmax(np.array(rows) ==2)for i, m inenumerate([red, green, blue, gray]):if0in rows: axs[idx0, i].axis('off') axs[idx0, i].invert_yaxis()if (1in rows) or (i <3): axs[idx0, i].text(0.15, 0.25, str(m.astype(np.uint8)), verticalalignment='top') axs[idx0, i].set_title(titles0[i], fontsize=16)if1in rows: axs[idx1, i].set_title(titles1[i], fontsize=16) axs[idx1, i].set_xlabel('5x5', fontsize=14) axs[idx1, i].imshow(m, cmap=plt.cm.gray)if2in rows: axs[idx2, i].set_title(titles2[i], fontsize=16) axs[idx2, i].set_xlabel(f'5x5x3 - {titles1[i][0]} only', fontsize=14)if i <3: stacked = [zeros] *3 stacked[i] = m axs[idx2, i].imshow(np.stack(stacked, axis=2))else: axs[idx2, i].imshow(rgb)for r in [1, 2]:if r in rows: idx = idx1 if r ==1else idx2 axs[idx, i].set_xticks([]) axs[idx, i].set_yticks([])for k, v in axs[idx, i].spines.items(): v.set_color('black') v.set_linewidth(.8)if1in rows: axs[idx1, 0].set_ylabel('Single\nChannel\n(grayscale)', rotation=0, labelpad=40, fontsize=12) axs[idx1, 3].set_xlabel('5x5 = 0.21R + 0.72G + 0.07B')if2in rows: axs[idx2, 0].set_ylabel('Three\nChannels\n(color)', rotation=0, labelpad=40, fontsize=12) axs[idx2, 3].set_xlabel('5x5x3 = (R, G, B) stacked') fig.tight_layout()return fig
ToTensor: Converts a PIL Image or numpy.ndarray (H x W x C) in the range [0, 255] to a torch.FloatTensor of shape (C x H x W) in the range [0.0, 1.0] if the PIL Image belongs to one of the modes (L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1) or if the numpy.ndarray has dtype = np.uint8
torch.as_tensor can work on N-dimensional arrays (ToTensor works only on 2D/3D images), but doesn’t apply scalling and, just fyi, it shares data i.e. doesn’t make a copy.
more options for different PIL modes: (L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1).
One has to be careful: - PIL gray images (L mode) need to be squeezed from 3D to 2D via np.squeeze() - RGB mode images should be floats between [0,1] - L mode (grayscale) images should be np.uint8 from [0,255] - 1 mode (bool) images are True or False.
PyTorch default floating point dtype is torch.float32, one can change this if needed via torch.set_default_dtype(torch.float64).
Samplers
One can also define a Sampler (and it’s subclasses: SequentialSampler, RandomSampler, SubsetRandomSampler, WeightedRandomSampler, BatchSampler, and DistributedSampler), use WeightedRandomSampler for example in case data is unbalanced.
# Builds a loader of each settrain_loader = DataLoader(dataset=dataset, batch_size=16, sampler=train_sampler)val_loader = DataLoader(dataset=dataset, batch_size=16, sampler=val_sampler)
Note that we need val_sampler just because we are passing the full dataset.
Also note that when using Samplers, one can’t use shuffle=True in DataLoaders.