【MATLAB】建立 VGG Face Dataset 人臉資料集

  • 510
  • 0
  • 2019-05-24

VGG-Face dataset 是由牛津大學視覺幾何組提供的人臉資料集。
其中有第一版 2622 人與第二版的 9131 人,非常好用。

資料載點:VGG-Face

1. 資料介紹

VGG-Face 解壓縮後,資料夾內可以看到三個檔案。
其中 files 就是我們需要的人臉圖片檔案......的載點。

這是為了避免人臉照片檔案過大還有規避版權的問題。

當我們點開檔案之後,大概長這樣:

00000001 ...(網址太長,略)
00000002 ...(略)
00000003 ...(略)
00000004 ...(略)
00000005 http://img31.mtime.cn/ph/525/930525/930525.jpg 28.19 65.33 111.43 148.57 4.00 3.60 0
...

每個人名都配有 1000 個網址。

其內容依序為:
1.編號。
2.圖片網址。
3.人臉方框(left, top, right, bottom),共 4 個數字。
4.姿勢,其值大於2表示正面,小於2表示側面。
5.偵測角度。
6.是否存在於專業資料庫。

在處理資料時,請自行決定需要使用哪些資料即可。

舉例來說,以上面第 5 條資料為例,撰寫一段 MATLAB 程式:

% MATLAB code

I = imread('http://img31.mtime.cn/ph/525/930525/930525.jpg');

bbox = [28.19 65.33 111.43 148.57];
bbox = [bbox(1), bbox(2), bbox(3)-bbox(1), bbox(4)-bbox(2)];

I1 = insertShape(I, 'Rectangle', bbox, 'Color', 'g', 'LineWidth', 2);
imshow(I1)

執行後可得到以下畫面:

2. 批次處理建檔

總共有 2622 人,每個人有 1000 張照片,當然是要寫程式搞定它!
相信不會有人想要一張一張地,用滑鼠點擊下載吧?

在此先行奉上處理檔案程式:

function txt2imgDateset
% MATLAB code
%
% Shayne, 2019.05.15

%% 載入資料夾
VGG_Dataset = datastore('vgg_face_dataset\files', 'IncludeSubfolders', 1);

% 計算檔案數量
numFiles = length(VGG_Dataset.Files);

% 建立影像資料夾
imgDataset = [pwd, '\dataset\'];
if ~exist(imgDataset, 'dir')
    mkdir(imgDataset) 
end

%% 下載資料

% 設定讀取影像數量
max_file_number = 10;

% 紀錄影像資訊
image_status = struct([]);
idx = 1;

for i = 1:numFiles
    % check folder
    str = strsplit(VGG_Dataset.Files{i}, {'\'});
    label = strrep(str{end}, '.txt', '');
    if ~exist([imgDataset, label], 'dir')
        mkdir([imgDataset, label])
    end
    
    fprintf('%d >>> %s\n', i, label)
    
    % read files
    data = readtable(VGG_Dataset.Files{i});
    data = table2cell(data);
    numData = size(data, 1);
    
    totalimgs = 1;
    for j = 1:numData

        if totalimgs > max_file_number
            break
        end
        
        try
            fprintf('   read %04d images ...', j)
            I = imread(data{j, 2});
            
            img_path = [imgDataset, label, '\img', num2str(j), '.jpg'];
            imwrite(I, img_path)
            
            totalimgs = totalimgs + 1;
            
            % save the information of image
            image_status(idx).path = img_path;
            image_status(idx).bbox = [data{j, 3}, data{j, 4}, data{j, 5}-data{j, 3}, data{j, 6}-data{j, 4}];
            idx = idx + 1;
            
            save image_status image_status
            fprintf(' O\n')
        catch
            fprintf(' Error\n')
        end
    end
end

程式執行結果:

由於每個人都有 1000 張影像,但使用者不見得需要這麼多。
像是夏恩自己只選了 500 人,每人 100 張就完成人臉辨識程式了。

因此透過 max_file_number 來設定每個人需要的影像張數。
例如本例中,max_file_number = 10; 表示每個人只會下載 10 張照片。
至於人數嘛......當然是透過 for i=1:numFiles 來決定要幾個人啦!

使用 numFiles 也就是 2622,表示就是全部的人都要;
如果只要 100 人,那就改成 for i=1:100 就好。

此外由於來自世界各國的網址都會失效或者無法連線的問題,
這邊就需要使用 try...catch 語法來跳過無法下載的圖片。

再來就是影像資訊:image_status。
這個變數見仁見智,在這邊夏恩只要路徑與人臉框,不需要其他資料,所以僅保留前面兩者。
若讀者有需要就把需要的東西加在後面即可,像是:image_status(idx).angle = data{ j , 8 };

最後,也是最重要的一點:

就算成功下載影像,也是有可能會載到錯誤的內容!

以上圖為例,img3 和 img14 都不是人臉的照片。
這可能是該網址有阻擋下載的防火牆,或者是原始連結已經被替換成其他影像,使用前請務必小心檢查。

工欲善其事,必先利其器。
想做好人臉辨識,就從一個好的資料集開始吧!