Raspberry Pi用 7色電子ペーパー Inky Impression 4でいろいろ表示してみる

技術メモ
技術メモ

セットアップ方法や画像表示方法、サンプルコードを実行してみた記録です。

使ったもの

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)】カラーパレットの設定(インデックスカラー)

【備忘録】PNGファイルからインデックスカラーを取得する

numpy配列から画像に変換する方法について

PythonのPillowのImage.fromarrayの使い方: 配列を画像に変換する

グラデーション画像作成方法について

Python, NumPyでグラデーション画像を生成

Python (Pillow)でグラデーション画像を作る

numpyの3次元配列について

Python: 3次元配列のイメージ (numpy.array)

ありがとうございました!

スポンサーリンク
スポンサーリンク
のぼをフォローする
のぼさんのブログ
タイトルとURLをコピーしました