Pythonでグラデーション画像生成[1]｜np.linspace

# はじめに
今回は[こちらの記事](https://note.nkmk.me/python-numpy-generate-gradation-image/)を参考に、pythonでグラデーション画像を生成しようと思います。

# グラデーション画像の生成
今回は二つの関数を用いて画像を生成します。

```python:gradation_2d_color
def gradation_2d_color(start, stop, size, is_horizontal):
    if is_horizontal:
        return np.tile(np.linspace(start, stop, size[1]), (size[0], 1))
    else:
        return np.tile(np.linspace(start, stop, size[0]), (size[1], 1)).T
```
startからstopまでの範囲をheight(またはwidth)の数だけ分割した等差数列の値を格納する長さheight(またはwidth)の１次元配列をnp.linspaceを用いて作り、これをnp.tileによりwidth(またはheight)の数だけ複製し格納した長さwidth(またはheight)の２次元配列を作ります。
・start：開始画素値
・stop：終了画素値
・size：画像サイズ[height,width]
・is_horizontal：True→水平方向にグラデーション変化/False→鉛直方向にグラデーション変化

```python:gradation_3d_img
def gradation_3d_img(start_list, stop_list, size, is_horizontal_list):
    result = np.zeros((size[0], size[1], len(start_list)), dtype=np.float)

    for i, (start, stop, is_horizontal) in enumerate(zip(start_list, stop_list, is_horizontal_list)):
        result[:, :, i] = gradation_2d_color(start, stop, size, is_horizontal)

    return result
```
それぞれrgbに対応するリストを渡します。第一要素がr成分、第二要素がg成分、第三要素がb成分のパラメータとなっています。
・start_list：開始画素値のリスト
・stop_list：終了画素値のリスト
・size：画像サイズのリスト
・is_horizontal_list：変化方向のリスト

これらの関数を用いてグラデーション画像を生成します。

```python:main
    size = [400,500] #height, width
    # 水平方向に黒→白
    img = gradation_3d_img([0,0,0], [255,255,255], size, [True,True,True])

    img = img.astype(np.uint8)
    img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
    cv2.imwrite('out.png', img)
```

# 出力画像
画像サイズを(400,500)として、他のパラメータを様々な値で試しました。

 - img = gradation_3d_img([0,0,0], [255,255,255], size, [True,True,True])
  - rgbの範囲：`rgb(0,0,0)`→`rgb(255,255,255)`
  - rgbの変化方向：[→, →, →]

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552715/98ea5f65-2b42-65dd-4d44-603c297cc44a.png width=50%> 
連続的に水平方向に`rgb(0,0,0)`から`rgb(255,255,255)`への色変化をしています。

 - img = gradation_3d_img([0,0,0], [255,255,255], size, [False,False,False])
  - rgbの範囲：`rgb(0,0,0)`→`rgb(255,255,255)`
  - rgbの変化方向：[↓, ↓, ↓]
  
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552715/64403f69-1c3a-7b94-8c64-dfba900b5076.png width=50%>
連続的に鉛直方向に`rgb(0,0,0)`から`rgb(255,255,255)`への色変化をしています。

 - img = gradation_3d_img([0,255,255], [255,255,255], size, [True,True,True])
  - rgbの範囲：`rgb(0,255,255)`→`rgb(255,255,255)`
  - rgbの変化方向：[→, →, →]
  
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552715/d538282f-e386-9b5f-4790-bf8757518b73.png width=50%>
 連続的に鉛直方向に`rgb(0,255,255)`から`rgb(255,255,255)`への色変化をしています。

 - img = gradation_3d_img([255,0,0], [0,255,255], size, [True,True,True])
  - rgbの範囲：`rgb(255,0,0)`→`rgb(0,255,255)`
  - rgbの変化方向：[→, →, →]

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552715/25a21e36-a3c6-5afd-e5cc-c8d751ff7c19.png width=50%> 
連続的に水平方向に`rgb(255,0,0)`から`rgb(0,255,255)`への色変化をしています。

 - img = gradation_3d_img([0,0,0], [255,255,255], size, [False,True,True])
  - rgbの範囲：`rgb(0,0,0)`→`rgb(255,255,255)`
  - rgbの変化方向：[↓, →, →]
 
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552715/0f64bcf6-62a3-683a-5d0a-8dbf721dfe85.png width=50%>
rの変化方向を鉛直方向↓にすると斜め方向に変化するようになりました。
具体的には、右斜め下↘︎方向に`rgb(0,0,0)`から`rgb(255,255,255)`への色変化を、右斜め上↗︎方向に`rgb(255,0,0)`から`rgb(0,255,255)`への色変化をしています。

 - img = gradation_3d_img([0,0,0], [255,255,255], size, [False,False,True])
  - rgbの範囲：`rgb(0,0,0)`→`rgb(255,255,255)`
  - rgbの変化方向：[↓, ↓, →]
 
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552715/cca5df4d-7a3a-f1fb-9979-cd079a4138c4.png width=50%>
次に、rとgの変化方向を鉛直方向↓にすると
右斜め上↗︎方向に`rgb(255,255,0)`から`rgb(0,0,255)`への色変化をしています。

# 今後の課題
今回のグラデーションは等差数列を生成するnp.linspaceを使って表現しました。
連続的に数値が変化するという意味でグラデーションを表現できていると思います。
しかし、他にもグラデーション変化を数値的に表現できるのではないかという疑問が浮かび上がってきました。次回はそれについて書こうと思います。