---
# System prepended metadata

title: Augmentor：影像數據增強工具庫
tags: [Python, 工具安裝與部署, 資訊科技 › 開發與輔助工具, 工具介紹與操作, 應用資訊 › 影像處理, 電腦視覺 CV, 資料轉換, AI/ML]

---

---
title: Augmentor：影像數據增強工具庫
date: 2020-01-15
is_modified: false
disqus: cynthiahackmd
categories:
- "應用資訊 › 影像處理"
- "資訊科技 › 開發與輔助工具"
tags:
- "AI/ML"
- "資料轉換"
- "電腦視覺 CV"
- "Python"
- "工具介紹與操作"
- "工具安裝與部署"
---

{%hackmd @CynthiaChuang/Github-Page-Theme %}

 
<br>

記錄一下最近使用的影像資料增強工具 - [Augmentor](https://augmentor.readthedocs.io/en/master/)，可用來做訓練圖像生成與雜訊添加...等

<!--more-->
## 簡介
<p class="illustration">
    <img src="https://i.imgur.com/thTW1NE.png" alt="AugmentorLogo">
    Augmentor Logo （圖片來源: <a href="https://github.com/taki0112/Augmentor">Augmentor</a>）
</p>


根據[文件簡介](https://augmentor.readthedocs.io/en/master/#augmentor)，Augmentor 是一個 Python Package，用於幫助機器學習任務的影像增強與生成。它主要是一種資料增強工具，但也提供了些基本的影像預處理功能。

影像處理[主要功能](https://augmentor.readthedocs.io/en/master/userguide/mainfeatures.html)包含：透視偏斜（Perspective Skewing）、彈性變形（Elastic Distortions）、
旋轉（Rotating）、推移（Shearing）、裁剪（Cropping）與鏡像（Mirroring）。當然最基礎的亮度、對比也有[支援](https://augmentor.readthedocs.io/en/master/code.html)。
 
由於影像增強通常是多階段的處理過程，因此 Augmentor 使用採用基於 pipeline 的處理方式，按使用者所選擇處理動作，依序添加到 pipeline 中。執行過程中，影像會被送進 pipeline 中，依序套用各個增強操作，最終形成新的影像。

另外，每個動作都可自定義套用機率，在影像經由 pipeline 時，會按機率決定是否套用該操作，以增加資料的多樣性。


↑ 以上全出自於 [Augmentor文件](https://augmentor.readthedocs.io/en/master/index.html)， Google 翻譯友情贊助 XDDD



## 安裝
我是透過 pip 安裝，所以還挺簡單，一條指令就搞定：

```shell=
$ pip install Augmentor
```


 
## 使用方法
 
### 純圖片增強
幾本上，就只有三個步驟：
<br>

首先，初始化 pipeline 物件，並指向所需處理影像的目錄
```python=
import Augmentor
p = Augmentor.Pipeline("./images")
```
<br>

接下來，添加所需的影像增強操作
```python=
p.random_contrast(probability=0.5, min_factor=0.3, max_factor=0.8)
p.random_brightness(probability=0.5, min_factor=0.5, max_factor=1.0)
p.zoom(probability=0.5, min_factor=1.01, max_factor=1.03)
p.random_distortion(probability=0.5, grid_height=3, grid_width=3, magnitude=6)
p.skew(probability=0.5, magnitude=0.12)
p.random_erasing(probability=0.5, rectangle_area=0.11)
p.rotate(probability=0.5, max_left_rotation=4, max_right_rotation=4)
```
<br>

最後，指定增強後圖片數目總量
```python=
p.sample(2000)
```



### 含圖片與標籤的增強
但通常在在進行模型訓練時，所取得資料不只圖片本身，還會有圖片相對應的標籤，此時 [`Augmentor.Pipeline` ]( https://augmentor.readthedocs.io/en/master/code.html#Augmentor.Pipeline.Pipeline)就不適用，應該改用 [`DataPipeline`](https://augmentor.readthedocs.io/en/master/code.html#Augmentor.Pipeline.DataPipeline)。

但需注意的是， `Pipeline` 所傳入的參數是==圖片位置==，但 `DataPipeline` 傳入是==圖片==。

```python=
import cv2
import Augmentor

batch_imgs = []  
batch_texts = []   

for i, file in enumerate(img_files):
   batch_imgs.append(cv2.imread(file))
   batch_texts.append(file)

# batch_imgs shape = (bs, 3)             
p = Augmentor.DataPipeline(batch_imgs, batch_texts)
```

<br>

原本以為這樣就可行了，但卻發現影像過了 pipeline 後，套用的影像增強不如預期，詳讀文件也沒找到可用的訊息，只好去細看他們所提供的[範例](https://github.com/mdbloice/Augmentor/blob/master/notebooks/Multiple-Mask-Augmentation.ipynb)。


果然在第五行的的程式碼中找到蛛絲馬跡，範例中是這樣的：
```python=
images = [[np.asarray(Image.open(y)) for y in x] for x in collated_images_and_masks]
```

發現它讀入圖片後，外面有多一層 array，所以當這個步驟結束時，預期的維度會是 3 維，而非我的 2 維。依照這個邏輯，再將圖片放入 `DataPipeline` 前，先==擴展維度==：
```python=
import cv2
import Augmentor

batch_imgs = []  
batch_texts = []   

for i, file in enumerate(img_files):
   batch_imgs.append(cv2.imread(file))
   batch_texts.append(file)

batch_imgs = np.expand_dims(batch_imgs, axis=1)
# batch_imgs shape = (bs, 1, 3)   
p = Augmentor.DataPipeline(batch_imgs, batch_texts)

```

<br>

最後再取出增強後圖片，與相對應的標籤。別忘了，記得把剛剛擴展維度的==維度降回去==：
```python
batch_imgs, batch_texts = p.sample(batch_size)
batch_imgs = np.squeeze(batch_imgs, axis=1)
```

如此出來的增強影像，看起來正常多了。


### 自定義增強器
說到增強，我想讓我的模型多看看不同色調下的圖片，所以翻了翻文件，好不容易找到 [`HSVShifting`](https://augmentor.readthedocs.io/en/master/code.html#Augmentor.Operations.HSVShifting)，結果竟然...

<font color="#f00">CURRENTLY NOT IMPLEMENTED</font>.  
<font color="#f00">CURRENTLY NOT IMPLEMENTED</font>.  
<font color="#f00">CURRENTLY NOT IMPLEMENTED</font>.  

登愣！！

<br>

只好來研究如何[自定義增強器](https://augmentor.readthedocs.io/en/master/userguide/extend.html)

#### 建立一個新的操作子類別
在建立一個新的操作子類別時，有四個地方需要注意的

1. 子類別要繼承 [`Operation`](https://augmentor.readthedocs.io/en/master/code.html#Augmentor.Operations.Operation)。
2. 初始化時，同時記得呼叫父類別 `__init__()`。
3. 重載（Overload）`perform_operation()`，以自定義新的增強。
4. `perform_operation()` 的回傳資料型態必須是 `PIL.Image`。

<br>

快速實做版簡單的 `HSVShifting` 進行驗證：
 
```python=
class CustomizeHSVShifting(Operation):
   def __init__(self, probability, max_h_shift=359, min_h_shift=1, max_s_shift=100, min_s_shift=0):
      Operation.__init__(self, probability)
      self.max_h_shift = max_h_shift
      self.min_h_shift = min_h_shift
      self.max_s_shift = max_s_shift
      self.min_s_shift = min_s_shift

   def perform_operation(self, images):
      def do(img):
         img = np.array(img)
         hsv_image = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)

         h_shift = random.randint(self.min_h_shift, self.max_h_shift)
         hsv_image[:, :, 0] = hsv_image[:, :, 0] + h_shift

         s_shift = random.randint(self.min_s_shift, self.max_s_shift)
         hsv_image[:, :, 1] = hsv_image[:, :, 1] + s_shift

         return Image.fromarray(cv2.cvtColor(hsv_image, cv2.COLOR_HSV2RGB))

      augmented_images = []

      for image in images:
         augmented_images.append(do(image))

      return augmented_images
```
<br>

注意，perform_operation 傳入的會是圖片陣列，而非單張圖片，別被[文件](https://augmentor.readthedocs.io/en/master/userguide/extend.html)中的 ==image== 這個字給騙了！實做時可以與其他功能的[實做](https://augmentor.readthedocs.io/en/master/_modules/Augmentor/Operations.html#RandomBrightness)進行對照。


#### 將操作子類別加到 pipeline 中
呼叫 [`add_operation`](https://augmentor.readthedocs.io/en/master/code.html#Augmentor.Pipeline.Pipeline.add_operation) 來進行添加：

```python=
p.add_operation(CustomizeHSVShifting(probability=0.5, max_h_shift=330, min_h_shift=30, max_s_shift=30, min_s_shift=0))
```

如此一來就將自定義的增加入 pipeline。



## 參考資料 
1. [Augmentor 0.2.6 documentation｜Augmentor](https://augmentor.readthedocs.io/en/master/)
2. [taki0112/Augmentor: Image augmentation library in Python for machine learning.｜GitHub](https://github.com/taki0112/Augmentor)
3. [Extending Augmentor｜Augmentor 0.2.6 documentation](https://augmentor.readthedocs.io/en/master/userguide/extend.html)
4. [資料增強利器–Augmentor｜程式前沿](https://codertw.com/%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80/463180/) 
5. [非常好用的Python图像增强工具，适用多个框架｜知乎](https://zhuanlan.zhihu.com/p/81952280) 

<br><br> 

> **本文作者**： 辛西亞．Cynthia  
> **本文連結**： [辛西亞的技能樹](https://cynthiachuang.github.io/Augmentor-Image-Augmentation-Library-in-Python) / [hackmd 版本](https://hackmd.io/@CynthiaChuang/Augmentor-Image-Augmentation-Library-in-Python)   
> **版權聲明**： 部落格中所有文章，均採用 [姓名標示-非商業性-相同方式分享 4.0 國際](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en) (CC BY-NC-SA 4.0) 許可協議。轉載請標明作者、連結與出處！