GANGAN(贋GAN)

# はじめに
**ジョーク記事ですので悪しからず.**

2018年はGANが大流行でしたね. 
DeepMindのインターン生が作ったというBigGANは, もう本物と区別が付かないようなクオリティです. 
![pics-generated (2).png](https://qiita-image-store.s3.amazonaws.com/0/144878/7dba07cd-254c-f899-3b83-0cf69ecaf23b.png)
[Large Scale GAN Training for High Fidelity Natural Image Synthesis](https://arxiv.org/abs/1809.11096)

また, フランスの芸術家集団ObviousがGANで生成した絵画をオークションに出したら43万ドルで落札されたというセンセーショナルなニュースもありました. 
![https_%2F%2Fjp.hypebeast.com%2Ffiles%2F2018%2F10%2Fai-art-portrait-christies-obvious-sold-432500-usd-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/144878/f76df3e8-9f85-523c-9e7e-12afcd00e9a1.jpeg)
[AI絵画, 大手オークションで初の落札 予想額の40倍超　写真4枚　国際ニュース：AFPBB News](http://www.afpbb.com/articles/-/3194763)
これを受けて「GAN(贋)作を掴まされた」なんてジョークも流行りましたね. 

この1年でGANが生成する画像は本物の画像に大きく近づいたと言えます. 
また, 個人的に最近GANの論文をいろいろと読んでいたせいか, 正方形の画像が縦横に並んでいると「GANだ！」と思うようになってしまいました. 
というわけで, 今回の記事では, 本物の画像をグリッド状に整列することでGANで生成したと見紛うような画像を作ります. 

こんな感じのものを目指します. 
![hakodate.png](https://qiita-image-store.s3.amazonaws.com/0/144878/9d059216-acb4-ada9-58c3-80e528e68013.png)

名付けて「**GANGAN(贋GAN)**」です.

# 手法
## データ
この前参加した函館開発合宿の写真を使います. 
例えば, 函館名物[ラッキーピエロ](http://luckypierrot.jp/). 
![IMG_20181111_133858.jpg](https://qiita-image-store.s3.amazonaws.com/0/144878/13c5dedc-7261-f820-a843-a81fb91318d7.jpeg)

## リサイズ
短辺の長さに合わせて中心を正方形でクロップしてから, 適当なサイズに縮小します. 

```python
im = Image.open(file)
w, h = im.size
w_mid, h_mid = int(w/2), int(h/2)
unit = int(min(w, h)/2)
im_crop = im.crop((w_mid-unit, h_mid-unit, w_mid+unit, h_mid+unit))
im_resize =  im_crop.resize((S,S))
```

## 整列
画像のリストを, `numpy`の`reshape`と`transpose`をがんばって組み合わせて整列させます. 
ここが一番難しかったです. 

```python
ims = np.array(ims)
ims = ims.reshape((5,5,S,S,3))
ims = ims.transpose(0,2,1,3,4)
ims = ims.reshape((5*S,5*S,3))
```
　
## コード
全体のコードです. 

```python
import glob
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

def main():
    S = 256 # size of one picture
    n_img = 5*5

    print('Enter relative path to the directry that has pictures:')
    dir_name = str(input())
    files =glob.glob(dir_name + '/*')
    ims = []
    for i,file in enumerate(files):
        if i>=n_img:
            break
        print(file)
        im = Image.open(file)
        w, h = im.size
        w_mid, h_mid = int(w/2), int(h/2)
        unit = int(min(w, h)/2)
        im_crop = im.crop((w_mid-unit, h_mid-unit, w_mid+unit, h_mid+unit))
        im_resize =  im_crop.resize((S,S))
        ims.append(np.array(im_resize))

    ims = np.array(ims)
    ims = ims.reshape((5,5,S,S,3))
    ims = ims.transpose(0,2,1,3,4)
    ims = ims.reshape((5*S,5*S,3))
    plt.imsave('result.png', ims)

if __name__=='__main__':
    main()
```

# おわりに
調べてみたら, アルバムジャケットをDCGANで生成している人がいました. 
![albums_128px.png](https://qiita-image-store.s3.amazonaws.com/0/144878/19d2d341-2f85-4f22-ce03-1508d1e3accd.png)
https://github.com/Newmu/dcgan_code

これをGANGANで生成すると…？
![result.png](https://qiita-image-store.s3.amazonaws.com/0/144878/7b4dc779-f70d-7f86-1a62-7c06ac813f70.png)
どっちが本物かわからなくなってきましたね？
Twitterで見かける[#私を構成する9枚](https://twitter.com/search?q=%23%E7%A7%81%E3%82%92%E6%A7%8B%E6%88%90%E3%81%99%E3%82%8B9%E6%9E%9A&src=tyah)にも使えます.

以上です. お付き合いいただきありがとうございました. 
~~GANをチューニングする時間と体力がなかった.~~

「このくらいなら自分でも書ける」と思った応物/OBOGのあなた！
まだ枠がありますのでぜひアドベントカレンダーに参加してください！