Pytorch 圖片載入

import os
import torch
import pandas as pd
from skimage import io, transform
import numpy as np
import matplotlib.pyplot as plt
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms, utils
# Ignore warnings
import warnings
warnings.filterwarnings("ignore")

載入圖片和坐標(biāo)

landmarks_frame = pd.read_csv('data/faces/face_landmarks.csv')
n=65
img_name = landmarks_frame.iloc[n, 0]  #獲取圖片的名稱
landmarks = landmarks_frame.iloc[n, 1:].as_matrix()  #獲取點(diǎn)的位置
landmarks = landmarks.astype('float').reshape(-1, 2)
landmarks_frame.iloc[:3, :] #展示一下csv里面的格式

<div>
<style scoped>
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}

.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}

</style>
<table border="1" class="dataframe">
<thead>
<tr style="text-align: right;">
<th></th>
<th>image_name</th>
<th>part_0_x</th>
<th>part_0_y</th>
<th>part_1_x</th>
<th>part_1_y</th>
<th>part_2_x</th>
<th>part_2_y</th>
<th>part_3_x</th>
<th>part_3_y</th>
<th>part_4_x</th>
<th>...</th>
<th>part_63_x</th>
<th>part_63_y</th>
<th>part_64_x</th>
<th>part_64_y</th>
<th>part_65_x</th>
<th>part_65_y</th>
<th>part_66_x</th>
<th>part_66_y</th>
<th>part_67_x</th>
<th>part_67_y</th>
</tr>
</thead>
<tbody>
<tr>
<th>0</th>
<td>0805personali01.jpg</td>
<td>27</td>
<td>83</td>
<td>27</td>
<td>98</td>
<td>29</td>
<td>113</td>
<td>33</td>
<td>127</td>
<td>39</td>
<td>...</td>
<td>93</td>
<td>136</td>
<td>100</td>
<td>141</td>
<td>93</td>
<td>135</td>
<td>89</td>
<td>135</td>
<td>84</td>
<td>134</td>
</tr>
<tr>
<th>1</th>
<td>1084239450_e76e00b7e7.jpg</td>
<td>70</td>
<td>236</td>
<td>71</td>
<td>257</td>
<td>75</td>
<td>278</td>
<td>82</td>
<td>299</td>
<td>90</td>
<td>...</td>
<td>148</td>
<td>311</td>
<td>179</td>
<td>308</td>
<td>149</td>
<td>312</td>
<td>137</td>
<td>314</td>
<td>128</td>
<td>312</td>
</tr>
<tr>
<th>2</th>
<td>10comm-decarlo.jpg</td>
<td>66</td>
<td>114</td>
<td>65</td>
<td>128</td>
<td>67</td>
<td>142</td>
<td>68</td>
<td>156</td>
<td>72</td>
<td>...</td>
<td>128</td>
<td>162</td>
<td>136</td>
<td>167</td>
<td>127</td>
<td>166</td>
<td>121</td>
<td>165</td>
<td>116</td>
<td>164</td>
</tr>
</tbody>
</table>
<p>3 rows × 137 columns</p>
</div>

接下來,是如何展示圖片朴下,以及把點(diǎn)畫在圖片之上

def show_landmarks(image, landmarks):
    fig, ax = plt.subplots()
    ax.imshow(image)
    ax.scatter(landmarks[:, 0], landmarks[:, 1], s=10, marker='.', c='r')
    plt.pause(0.001)  #暫停讓圖片更新?
    plt.show()
    
show_landmarks(io.imread(os.path.join('data/faces/', img_name)),
              landmarks)
    
在這里插入圖片描述

torch.utils.data.Dataset是一個(gè)抽象基類表示一個(gè)數(shù)據(jù)集,我們需要為其設(shè)定_len方法和_getitem方法.

class FaceLandmarksDataset(Dataset):
    def __init__(self, csv_file, root_dir, transform=None):
        self.landmarks_frame = pd.read_csv(csv_file)
        self.root_dir = root_dir
        self.transform = transform
        
    def __len__(self):
        return len(self.landmarks_frame)
    
    def __getitem__(self, idx):
        img_name = os.path.join(self.root_dir,
                               self.landmarks_frame.iloc[idx, 0])
        image = io.imread(img_name)
        landmarks = self.landmarks_frame.iloc[idx, 1:]
        landmarks = np.array([landmarks])
        landmarks = landmarks.astype('float').reshape(-1, 2)
        sample = {'image': image, 'landmarks': landmarks}
        
        if self.transform:
            sample = self.transform(sample)
            
        return sample

利用這個(gè)類图毕,我們來展示一下前4幅圖像

face_dataset = FaceLandmarksDataset(csv_file='data/faces/face_landmarks.csv', 
                                    root_dir='data/faces/')

def show_landmarks(image, landmarks):
    plt.imshow(image)
    plt.scatter(landmarks[:, 0], landmarks[:, 1], s=10, marker='.', c='r')
    plt.pause(0.001)  #暫停讓圖片更新?
    
fig = plt.figure()
for i in range(len(face_dataset)):
    sample = face_dataset[i]
    print(i, sample['image'].shape, sample['landmarks'].shape)
    
    ax = plt.subplot(1, 4, i+1)
    plt.tight_layout()
    ax.set_title("Sample #{}".format(i))
    ax.axis("off")
    show_landmarks(**sample)
    if i == 3:
        plt.show()
        break
0 (324, 215, 3) (68, 2)
在這里插入圖片描述
1 (500, 333, 3) (68, 2)
在這里插入圖片描述
2 (250, 258, 3) (68, 2)
在這里插入圖片描述
3 (434, 290, 3) (68, 2)
在這里插入圖片描述

Transforms

很多時(shí)候,我們需要對(duì)圖片進(jìn)行一些變化悼尾,比方說大小的調(diào)整等等

利用函子(_call_)能夠很好很方便對(duì)圖片進(jìn)行處理

class Rescale(object):
    """Rescale the image in a sample to a given size.

    Args:
        output_size (tuple or int): 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)) #output_size應(yīng)當(dāng)是一個(gè)整數(shù)或者元組
        self.output_size = output_size

    def __call__(self, sample):
        image, landmarks = sample['image'], sample['landmarks']

        h, w = image.shape[:2]
        if isinstance(self.output_size, int): #如果是一個(gè)整數(shù)缔逛,那么縮放的邏輯是要保持比例
            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 are axis 1 and 0 respectively
        landmarks = landmarks * [new_w / w, new_h / h] #坐標(biāo)也要相應(yīng)改變大小

        return {'image': img, 'landmarks': landmarks}
class RandomCrop(object): #隨機(jī)裁剪遭垛,但是實(shí)際上是一整塊來的
    """Crop randomly 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(output_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.randint(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': landmarks}


class ToTensor(object):
    """Convert ndarrays in sample to Tensors."""

    def __call__(self, sample):
        image, landmarks = sample['image'], sample['landmarks']

        # swap color axis because
        # numpy image: H x W x C
        # torch image: C X H X W
        image = image.transpose((2, 0, 1)) #把ndarray轉(zhuǎn)換為tensor需要改變順序
        return {'image': torch.from_numpy(image),
                'landmarks': torch.from_numpy(landmarks)}

Compose transforms

利用torchvision.transforms.Compose可以幫助我們對(duì)一個(gè)圖片進(jìn)行多個(gè)操作

scale = Rescale(256)
crop = RandomCrop(128)
composed = transforms.Compose([Rescale(256),
                               RandomCrop(224)])

# Apply each of the above transforms on sample.
fig = plt.figure()
sample = face_dataset[65]
for i, tsfrm in enumerate([scale, crop, composed]):
    transformed_sample = tsfrm(sample)

    ax = plt.subplot(1, 3, i + 1)
    plt.tight_layout()
    ax.set_title(type(tsfrm).__name__)
    show_landmarks(**transformed_sample)

plt.show()
在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

數(shù)據(jù)集的迭代

我們可以用 for ... in ... 來迭代數(shù)據(jù)集,但是這么做并不方便节槐,因?yàn)楹芏鄷r(shí)候訓(xùn)練神經(jīng)網(wǎng)絡(luò)是要分批和打亂順序的torch.utils.data.DataLoader可以幫助我們完成這一個(gè)目標(biāo)

transformed_dataset = FaceLandmarksDataset(csv_file='data/faces/face_landmarks.csv',
                                           root_dir='data/faces/',
                                           transform=transforms.Compose([
                                               Rescale(256),
                                               RandomCrop(224),
                                               ToTensor()
                                           ]))
dataloader = DataLoader(transformed_dataset, batch_size=4,
                        shuffle=True, num_workers=0) #batch_size: batch的大小 shuffle=True表示順序打亂
def show_landmarks_batch(sample_batched):
    """Show image with landmarks for a batch of samples."""
    images_batch, landmarks_batch = \
            sample_batched['image'], sample_batched['landmarks']
    batch_size = len(images_batch)
    im_size = images_batch.size(2)
    grid_border_size = 2

    grid = utils.make_grid(images_batch) #為圖片加入邊框
    plt.imshow(grid.numpy().transpose((1, 2, 0)))

    for i in range(batch_size):
        plt.scatter(landmarks_batch[i, :, 0].numpy() + i * im_size + (i + 1) * grid_border_size, #既然圖片加了邊框搀庶,而且并排放置,所以我們需要把這部分加上去
                    landmarks_batch[i, :, 1].numpy() + grid_border_size,
                    s=10, marker='.', c='r')

        plt.title('Batch from dataloader')

for i_batch, sample_batched in enumerate(dataloader):
    print(i_batch, sample_batched['image'].size(),
          sample_batched['landmarks'].size())


    if i_batch == 0:
        plt.figure()
        show_landmarks_batch(sample_batched)
        plt.axis('off')
        plt.ioff()
        plt.show()
        break
0 torch.Size([4, 3, 224, 224]) torch.Size([4, 68, 2])
224
在這里插入圖片描述
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末地来,一起剝皮案震驚了整個(gè)濱河市币绩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌田巴,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件攀甚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)僧免,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屋剑,你說我怎么就攤上這事“ω遥” “怎么了孕讳?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我厂财,道長(zhǎng)芋簿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任蟀苛,我火速辦了婚禮益咬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘帜平。我一直安慰自己幽告,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布裆甩。 她就那樣靜靜地躺著冗锁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嗤栓。 梳的紋絲不亂的頭發(fā)上冻河,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音茉帅,去河邊找鬼叨叙。 笑死,一個(gè)胖子當(dāng)著我的面吹牛堪澎,可吹牛的內(nèi)容都是我干的擂错。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼樱蛤,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼钮呀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起昨凡,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤爽醋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后便脊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚂四,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年就轧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了证杭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡妒御,死狀恐怖解愤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乎莉,我是刑警寧澤送讲,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布奸笤,位于F島的核電站,受9級(jí)特大地震影響哼鬓,放射性物質(zhì)發(fā)生泄漏监右。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一异希、第九天 我趴在偏房一處隱蔽的房頂上張望健盒。 院中可真熱鬧,春花似錦称簿、人聲如沸扣癣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽父虑。三九已至,卻和暖如春授药,著一層夾襖步出監(jiān)牢的瞬間士嚎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工悔叽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留莱衩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓娇澎,卻偏偏與公主長(zhǎng)得像膳殷,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子九火,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容