raspberry pi 4とinky impressionが入る筐体を作る（画像自動生成＆更新フォトフレームの作成）その3

## AIに画像を書かせて定期的に更新されるフォトフレームを作りたい！！
raspberry pi 4でStable Diffusionを動かしてみる（画像自動生成＆更新フォトフレームの作成）その2

https://qiita.com/kyazoooo/items/001271c3a8bc76086573

の続きになります。

# ここまで作業した内容
ここまでにStable Diffusionを使った画像生成と、
inky impressionへの画像描画がPythonで実行できるようになりました。

なのでその２つを統合してフォトフレームとして、放置していても画像が生成/表示され続けるものにしたいと思います。

# 構築作業1：プロジェクトディレクトリの作成
ホームディレクトリにプロジェクトフォルダを作り、そこに必要資材を構築していきます。

```
$ cd ~/
$ mkdir aiproject

// 画像保管用
$ mkdir aiproject/photo
$ cd aiproject
```

Python初心者ですがフォトフレーム用のコードを書いてみました。
```
$ vi aiPhotoFrame.py
```

```aiPhotoFrame.py
from diffusers import StableDiffusionPipeline, EulerDiscreteScheduler
from PIL import Image
from inky.inky_uc8159 import Inky
from datetime import datetime
import time

model_id = "stabilityai/stable-diffusion-2"
scheduler = EulerDiscreteScheduler.from_pretrained(model_id, subfolder="scheduler")
pipe = StableDiffusionPipeline.from_pretrained(model_id, scheduler=scheduler)
pipe = pipe.to("cpu")
prompt = "space cat  Anthropomorphized cat, casting evil spell, magic the gathering artwork, D&D, fantasy, cinematic lighting, centered, symmetrical, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, volumetric lighting, epic Composition, 8k, art by Akihiko Yoshida and Greg Rutkowski and Craig Mullins, heroic pose, oil painting, cgsociety, magic lab"
directory = "/home/pi/aiproject/photo/"

def makeArtWorker():
  try:
    # inky impression用に画像サイズを最適化（ここは64の倍数のピクセルのみ指定可能）
    image = pipe(prompt, height=448, width=640).images[0]
    date = datetime.now().strftime("%Y%m%d_%H%M%S")
    path = directory + date + ".png"
    image.save(path)
    time.sleep(1)
    displayArtWorker(path)
    
  except Exception as e:
    print("makeArtWorker error", e)
    time.sleep(10)

def displayArtWorker(photoPass):
  try:
    img = Image.open(photoPass)
    w, h = img.size
    h_new = 448
    w_new = int((float(w) / h) * h_new)
    w_cropped = 600
    img = img.resize((w_new, h_new), resample=Image.LANCZOS)
    x0 = (w_new - w_cropped) / 2
    x1 = x0 + w_cropped
    y0 = 0
    y1 = h_new
    img = img.crop((x0, y0, x1, y1))
    inky = Inky()
    # saturation 彩度
    saturation = 0.5 
    inky.set_image(img, saturation=saturation)
    time.sleep(1)
    inky.show()
    makeArtWorker()
  except Exception as e:
    print("displayArtWorker error",e)
    time.sleep(10)

makeArtWorker()

```

実行するとまず画像生成が走り、終わるとその画像をinky impressionに描画させるという一連の流れをループするだけの処理になっています。

![スクリーンショット 2023-03-31 19.11.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/a57ac215-1de8-e7b4-80b8-1dd30083e803.png)

これで数時間まつとが更新されるフォトフレームが完成しました！

あとは電源が入った際に自動起動させたいので、
```
$ crontab -e
```
で最後の行に以下を追加しました。

```
@reboot python3 /home/pi/aiproject/aiPhotoFrame.py
```
これで起動すれば勝手に動いてくれると思います。

# 構築作業２：仕上げ
中身は無事にできましたがこのままだと飾りにくくそして、Raspberry Piの発熱ですぐにでも壊れてしまいそうなので外側も作っていきます。

まずファンを2つ購入しました。

https://www.amazon.co.jp/gp/product/B00UWIB68U/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1

こちらを組み込める筐体をFusion360で作っていきます。
![スクリーンショット 2023-03-31 19.27.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/7de5c982-82eb-fa5d-7304-2a4b249a3b27.png)

そしたらこれをdxfにしてレーザ加工していきます。（一応データも置いておきます）
https://drive.google.com/file/d/1XjsZMNlUbNHcT4E5DEM1hWlE9doUeUxR/view?usp=share_link

レーザー加工機は以下の記事に書いてるものを使っていて、カットする素材はMDFの2.5mm厚のものを使います。

https://qiita.com/kyazoooo/items/147a2829f6a145d12859

加工が終わったらグルーガンとかで固定しつつ完成したものがこちらです。

![20230330_230819 (1).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/8ac6294b-8335-7eac-f44a-2b322c741487.jpeg)
![20230330_231117 (1).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/de8442ad-9540-5177-d4d4-4bd8fad0c9f8.jpeg)

ファンの電源はinky-impressionのここから5[v]を引きました。
![スクリーンショット 2023-03-31 19.37.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/9055e9c8-8cfe-50ed-e7bb-50a93038b793.png)

ファンを２つつけたこともあってかなり騒音ですが冷えてる感じがします、、！

<iframe width="560" height="315" src="https://www.youtube.com/embed/Reu5DjeuXJs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

この記事は以上です。