セットアップ方法や画像表示方法、サンプルコードを実行してみた記録です。
使ったもの
Raspberry Pi 2 Model B
Inky Impression 4
わたしはスイッチサイエンスさんで購入しました。
動作環境
pythonと使用ライブラリ
Python 3.7.3
inky 1.4.0
seaborn 0.12.2
Raspberry pi OSとカーネル
Description: Raspbian GNU/Linux 10 (buster)
Linux raspberrypi 5.10.103-v7+ #1529 SMP Tue Mar 8 12:21:37 GMT 2022 armv7l GNU/Linux
セットアップ方法
電子ペーパーのセットアップ方法と使い方はGitHubのリポジトリに載っていますが、自分用の備忘録として記録しました。
Raspberry Piと電子ペーパーを接続する
Raspberry Piの電源を入れる前に行います。
電子ペーパーには以下の2つが付属しています。
- gpioピン高さ調整用のピンヘッダー メス
- Raspberry Piと電子ペーパーを固定するピン
まずRaspberry Piに高さ調整用ピンヘッダー メスを差し込みます。これがないと電子ペーパーがRaspberry PiのUSBコネクタ メスに当たりセットできません。
電子ペーパーには固定用のピンを取り付けます。結構固かったです。
電子ペーパーのソケットとRaspberry Piのピンを差込み、付属のねじで固定ピンを止めます。
接続完了です。
IC2とSPIを有効にする
デフォルトではIC2とSPIがオフになっています。
ターミナルでsudo raspi-configを実行し、Interface OptionsからIC2とSPIをそれぞれenabledに変更します。
inkyライブラリのインストール
ターミナルで以下を実行します。
pip3 install inky
リポジトリをクローンする
同じくこちらもターミナルで実行。
git clone https://github.com/pimoroni/inky.git
これで準備完了です。
画像を表示させる
こちらの画像はぱくたそさんでダウンロードしました。とてもきれいです。
幅800px、高さ533pxのjpgファイルです。
以下のコードで表示させてみます。
from PIL import Image
from inky.auto import auto
inky = auto(ask_user=True, verbose=True)
img = Image.open("/home/nobo/Downloads/pic.jpg")
img = img.resize(inky.resolution)
inky.set_image(img, saturation = 0.5)
inky.show()
"""
結果
Detected 7-Colour 640x400 (UC8159)
"""
元の画像と比べると結構違いますが、本当に7色?ってくらいきれいに表示されますね。
自分でコードを書かなくても後述のサンプルコードimage.pyを使ってターミナルから表示させることも可能です。
saturationを変更してみる
saturation(彩度)を指定できるので、試しに0.3、0.5、0.8で表示させてみました。
ちょっとわかりにくいですが、下の方の赤いチューリップがsaturation0.3は白が少し混ざっているのに対して0.8は赤で塗りつぶされているような感じになっていいる気がします。
7色(赤・青・黄・橙・緑・黒・白)以外の色を表示してみる
試しに7色以外の色を表示してみました。
ピンク(R255, G0, B255)と水色(R0, G255, B255)のグラデーション画像を作成し表示してみます。
from PIL import Image
import numpy as np
from inky.auto import auto
inky = auto(ask_user=True, verbose=True)
width, height = inky.resolution
top_RGB = [255, 0, 255]
bottom_RGB = [0, 255, 255]
arr_3d = np.zeros((height, width, 3), dtype=np.float64)
for i, (top, bottom) in enumerate(zip(top_RGB, bottom_RGB)):
arr_3d[:, :, i] = np.tile(np.linspace(top, bottom, height), (width, 1)).T
im = Image.fromarray(np.uint8(arr_3d))
im.show()
im.save("/home/nobo/Downloads/gradation-pic.jpg", quality=95)
inky.set_image(im, saturation = 0.5)
inky.show()
グラデーションのnumpy3次元配列のイメージは下図のとおりです。
表示した結果はこのようになりました。↓
電子ペーパーでは上から赤→青→緑のグラデーションですね。
どうやって元画像を表示可能な7色に変換しているのか気になりinky_uc8159.pyの中身(def _palette_blend()、def set_image()あたり)と公式サイトのブログを確認してみると7色用のカラーパレットを作成して、画像を変換してくれているみたいです。
エンジニアでもないただの素人なので間違ってたらごめんなさい。
試しに以下のコードでカラーパレットを作成して先ほどのグラデーション画像を変換後、pngで保存してみました。
from PIL import Image
import numpy as np
DESATURATED_PALETTE = [
[0, 0, 0],
[255, 255, 255],
[0, 255, 0],
[0, 0, 255],
[255, 0, 0],
[255, 255, 0],
[255, 140, 0],
[255, 255, 255]
]
SATURATED_PALETTE = [
[57, 48, 57],
[255, 255, 255],
[58, 91, 70],
[61, 59, 94],
[156, 72, 75],
[208, 190, 71],
[177, 106, 73],
[255, 255, 255]
]
def _palette_blend(saturation, dtype='uint8'):
saturation = float(saturation)
palette = []
for i in range(7):
rs, gs, bs = [c * saturation for c in SATURATED_PALETTE[i]]
rd, gd, bd = [c * (1.0 - saturation) for c in DESATURATED_PALETTE[i]]
if dtype == 'uint8':
palette += [int(rs + rd), int(gs + gd), int(bs + bd)]
if dtype == 'uint24':
palette += [(int(rs + rd) << 16) | (int(gs + gd) << 8) | int(bs + bd)]
if dtype == 'uint8':
palette += [255, 255, 255]
if dtype == 'uint24':
palette += [0xffffff]
return palette
pal_img = Image.new("P",(1,1))
palette = _palette_blend(0.5, dtype='uint8') + [0,0,0]*248
pal_img.putpalette(palette)
img = Image.open("/home/nobo/Downloads/gradation-pic.jpg")
img_convert = img.quantize(palette=pal_img)
print(np.array(img_convert.getpalette()).reshape(-1,3))
img_convert.save("/home/nobo/Downloads/convert-gradation-pic.png", quality=95)
"""
結果
[[ 28 24 28]
[255 255 255]
[ 29 173 35]
[ 30 29 174]
[205 36 37]
[231 222 35]
[216 123 36]
[255 255 255]
[ 0 0 0]
[ 0 0 0]
・・・省略・・・
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]
"""
結果(convert-gradation-pic.png)
うーん。表示された画像と絶妙に違う。。。
電子ペーパーの表示に約30秒ほどかかるので、どんなふうに表示されるか、事前にざっくりと確認してみるのもよさそうですね。
サンプルを動かしてみる
inky/examples/7color内のサンプルを動かしてみました。
全部で7種類あります。
stripes.py
7色を等幅のストライプ状に出力するサンプルです。
nobo@raspberrypi:~/Pimoroni/inky/examples/7color $ python3 stripes.py
上から黒、白、緑、青、赤、黄、橙です。
cycle.py
画面全体の色が黒→白→緑→青→赤→黄→橙の順に切り替わるサンプルです。
nobo@raspberrypi:~/Pimoroni/inky/examples/7color $ python3 cycle.py
1画面あたりの表示時間は5.0sです。
colour-palette.py
表示される色コードを取得できるサンプルです。
- –type、-t : “css”、”act”、”raw”、”pal”、”gpl”から選択。
- –saturation、-s : floatで指定。デフォルトは0.5。
- -file、-f : 書込むファイル
試しに-tをgpl、-sを0.5、-fにテキストファイルを指定して実行してみました。
nobo@raspberrypi:~/Pimoroni/inky/examples/7color $ python3 colour-palette.py -t “gpl” -s 0.5 -f “/home/nobo/Documents/colour-palette-test.txt”
GIMP Palette
Name: InkyImpressions
Columns: 7
28 24 28 Index 0 # black
255 255 255 Index 1 # white
29 173 35 Index 2 # green
30 29 174 Index 3 # blue
205 36 37 Index 4 # red
231 222 35 Index 5 # yellow
216 123 36 Index 6 # orange
saturationの値を変更すると結果が変化します。
graph.py
seabornのデータセットを表示するサンプルです。
- –dataset、-d : “penguins”、”dots”、”mpg”から選択。
デフォルトはmpg
使用するためにはseabornとlibatlas-base-devのインストールが必要。
sudo python3 -m pip install seaborn
sudo apt install libatlas-base-dev
試しにpenguinsのデータセットを表示します。
nobo@raspberrypi:~/Pimoroni/inky/examples/7color $ python3 graph.py -d “penguins”
ディスプレイが小さいので文字が読めるか心配でしたが、思っていたより見えやすいです。
buttons.py
電子ペーパー横にある4つボタン(上からA、B、C、D)を押すと対応しているGPIOピン番号とボタン名を出力してくれるサンプルです。
試しに実行し、A→B→C→Dの順にボタンを押してみました。
nobo@raspberrypi:~/Pimoroni/inky/examples/7color $ python3 buttons.py
buttons.py – Detect which button has been pressed
This example should demonstrate how to:
1. set up RPi.GPIO to read buttons,
2. determine which button has been pressed
Press Ctrl+C to exit!
Button press detected on pin: 5 label: A
Button press detected on pin: 6 label: B
Button press detected on pin: 16 label: C
Button press detected on pin: 24 label: D
Ctrl+Cを押すと終了します。
clear.py
画面全体を白にするサンプルです。
nobo@raspberrypi:~/Pimoroni/inky/examples/7color $ python3 clear.py
image.py
指定した画像を表示するサンプルです。
1番目のコマンドライン引数に画像ファイル名、2番目の引数にsaturation(彩度)を指定します。
2番目の引数を指定しない場合、saturationはデフォルトの0.5になります。
試しにsaturation0.8で表示してみます。
nobo@raspberrypi:~/Pimoroni/inky/examples/7color $ python3 image.py “/home/nobo/Downloads/pic.jpg” 0.8
さいごに
サンプルコードがたくさんあるのでそれをもとにいろいろと作れそうです。
公式サイトのブログでは制作アイデアとして
- 5日間の天気予報
- to do リスト
- ニュースのヘッドライン
などが提案されていました。
わたしはサンプルコードbutton.pyとimage.pyを参考にボタンで画面が切替わる天気カレンダーをつくってみました。
つくりかたを載せているので、よかったら見てみてください。
参考サイト
pillowのパレットモードについて
【Python/Pillow(PIL)】カラーパレットの設定(インデックスカラー)
numpy配列から画像に変換する方法について
PythonのPillowのImage.fromarrayの使い方: 配列を画像に変換する
グラデーション画像作成方法について
numpyの3次元配列について
Python: 3次元配列のイメージ (numpy.array)
ありがとうございました!