Take it straight from pytorch tutorials and see.
Required Packages:
1. Scikit-image: Image io and morphing
2. Pandas: Read in CSV file
Data:
Faces
Data form of CSV:
A total of 68 face key points.
image_name,part_0_x,part_0_y,part_1_x,part_1_y,part_2_x, part_67_x,part_67_y
0805personali01.jpg, 27,83,27,98, ... 84,134
1084239450_e76e00b7e7.jpg,70,236,71,257, ..., 128,312
Or as Pictured:
the simplest to read a picture through a function
#-*-Coding:utf-8-*-"" "Data Loading and processing Tutorial ==================================== **author**: ' Sasank Chilamkurthy
by inheriting a dataset
# when customizing the dataset, inherit the DataSet class.
# generally at least __init__, __len__, __getitem__ class Facelandmarksdataset (DataSet): "" "Face Landmarks Dataset." " def __init__ (self, csv_file, Root_dir, Transform=none): "" "Args:csv_file (String): Path to T
He csv file with annotations.
Root_dir (String): Directory with all the images.
Transform (callable, optional): Optional transform to is applied on a sample. "" "Self.landmarks_frame = Pd.read_csv (csv_file) Self.root_dir = Root_dir Self.transform = TRANSFO RM def __len__ (self): return Len (self.landmarks_frame) def __getitem__ (self, idx): img_name = OS . Path.join (Self.root_dir, SELF.LANDMARKS_FRAME.IX[IDX, 0]) image = Io.imread (img_name) landmarks = self.la Ndmarks_frame.ix[idx, 1:].as_matrix (). Astype (' float ') landmarks = Landmarks.reshape ( -1, 2) sample = {' Imag
E ': Image, ' Landmarks ': landmarks}If self.transform:sample = Self.transform (sample) # Use this, yes.
Return sample Face_dataset = Facelandmarksdataset (csv_file= ' faces/face_landmarks.csv ', Root_dir= ' faces/') FIG = plt.figure () for I in Range (len (face_dataset)): sample = Face_dataset[i] Print (i,
sample[' image '].shape, sample[' landmarks '].shape) # for Dict, you can use [' key '] to get the value. Ax = Plt.subplot (1, 4, i + 1) plt.tight_layout () ax.set_title (' Sample #{} '. Format (i)) Ax.axis (' Off ') show_
Landmarks (**sample) # keyword parameter pass if i = = 3:plt.show () break
Part III: Basic notation for Image transformations (Inherit object)
Mainly include:
1. Scaling Down
2. Random cropping
3. Convert the NumPy image data to tensor.
Other:
1. This changes the class to a callable object. Implementing Call () through the class
Like what:
TSFM = Transform (init_params)
Transformed_sample = TSFM (call_params)
is the instance (parameter) of the class.
Knowledge Points:
1. Isinstance (output_size, (int, tuple)) * * The following parameters can be of tuple. To validate multiple types at the same time.
2. NumPy and Pytorch images are to be swap axis.
# Swap Color Axis because
# numpy image:h x W x C
# torch Image:c x H x W
image = Image.transpose ((2, 0, 1))
return {' Image ': torch.from_numpy (image),
' landmarks ': Torch.from_numpy (Landmarks)}
Class Rescale (object): "" "Rescale the image in a sample to a given size. Args:output_size (tuple or tuple): desired output size. If tuple, output is matched to output_size.
If int, smaller of image edges is matched to output_size keeping aspect ratio the same.
"" "Def __init__ (Self, output_size): Assert Isinstance (output_size, (int, tuple)) # good. Self.output_size = Output_size def __call__ (self, sample): image, landmarks = sample[' image '], sample[' LANDMA
Rks '] h, w = image.shape[:2] If isinstance (self.output_size, int): If h > w: New_h, new_w = self.output_size * h/w, self.output_size else:new_h, new_w = Self.output_ Size, Self.output_size * w/h else:new_h, new_w = Self.output_size new_h, new_w = Int (new_h ), int (new_w) img = transform.resize (image, (New_h, New_w)) # h and W are swaPped for landmarks because for images, # x and y axes is axis 1 and 0 respectively landmarks = landmarks * [new_w/w, new_h/h] return {' Image ': img, ' landmarks ': Landmarks} class Randomcrop (object): "" "" Crop RA
Ndomly the image in a sample. Args:output_size (tuple or int): desired output size.
If int, square crop is made. "" "Def __init__ (Self, output_size): Assert Isinstance (output_size, (int, tuple)) if Isinstance (OUTPU t_size, int): Self.output_size = (output_size, output_size) Else:assert Len (output_size) = = 2 Self.output_size = output_size def __call__ (self, sample): image, landmarks = sample[' image ' ], sample[' landmarks '] h, w = image.shape[:2] new_h, new_w = self.output_size top = Np.random.ra
Ndint (0, h-new_h) left = Np.random.randint (0, w-new_w) image = Image[top:top + New_h, Left:left + new_w] landmarks = landmarks-[left, top] return {' image ': image, ' landmarks ': LANDMA
Rks} class Totensor (object): "" "Convert ndarrays in the sample to tensors." " def __call__ (self, sample): image, landmarks = sample[' image '], sample[' landmarks '] # Swap color axis bec
Ause # numpy Image:h x W x C # Torch Image:c x H x W image = Image.transpose ((2, 0, 1)) return {' Image ': torch.from_numpy (image), ' Landmarks ': Torch.from_numpy (Landmarks)}
Part IV: Using Torchvision to combine image transformations
If we want to make multiple transformations on an image, we can use Torchvision.transforms.Compose.
""
Note:
1. Facelandmarksdataset is the second part of our custom class (inherited from the dataset).
2. Transforms. Compose can combine multiple operations.
3. Each operation is a class and has a __call__ function. The parameter of the __CALL__ function is sample. We only need mytransforms (Init_params). "" "
Transformed_dataset = Facelandmarksdataset (csv_file= ' faces/face_landmarks.csv ',
root_dir= ' faces /',
transform=transforms. Compose ([
rescale
], Randomcrop (224),
Totensor () # to tensor initialization function without parameters
])
# very ugly load dataset
for I in range (len (transformed_dataset)):
sample = Transformed_dataset[i]
print (i, sample[' image '). Size (), sample[' landmarks '].size ())
if i = = 3: Break
There are a number of problems with the method of working with datasets through this for loop:
1. No data is processed in batch form
2. No Shuffle data
3. No parallel loading data, with multiprocessing workers. Part V: Using Dataloader
The Torch.utils.data.DataLoader is an iterator with all of the above functional features.
Way
Dataloader = Dataloader (custom datasets via various transformations, batch_size=4,
shuffle=true, num_workers=4)
#定义dataload Dataloader = Dataloader (Transformed_dataset, batch_size=4, Shuffle=true, num_workers=4 ) # Helper function to show a batch def show_landmarks_batch (sample_batched): "" "show image with landmarks for a bat
CH of samples. "" " Images_batch, Landmarks_batch = \ sample_batched[' image '], sample_batched[' landmarks '] batch_size = Len (im Ages_batch) im_size = images_batch.size (2) Grid = Utils.make_grid (Images_batch) plt.imshow (Grid.numpy (). trans
Pose ((1, 2, 0))) for I in Range (batch_size): Plt.scatter (Landmarks_batch[i,:, 0].numpy () + i * im_size, Landmarks_batch[i,:, 1].numpy (), s=10, marker= '. ', c= ' R ') Plt.title (' Batch F
Rom Dataloader ') for I_batch, sample_batched in Enumerate (Dataloader): Print (I_batch, sample_batched[' image '].size (),
sample_batched[' landmarks '].size () # Observe 4th batch and stop.
if I_batch = = 3:plt.figure () Show_landmarks_batch (sample_batched) plt.axis (' Off ') Plt.ioff () Plt.show () break
Summary
The following are:
#-*-Coding:utf-8-*-############# First step: Prepare ################## "" Data Loading and processing Tutorial =============== ===================== **author**: ' Sasank chilamkurthy
The
can be seen, this method needs to write various transforms classes, more cumbersome. But the whole process can be clearly demonstrated. The following article describes the methods used in the real project.