最近7.3インチの7色カラー電子ペーパーを使用してフォトフレームを作成しましたが、新型の13.3インチ6色カラー電子ペーパーを新たに入手したので、以前の電子ペーパーと画質を比較して、フォトフレームを作りました。
今回使用した電子ペーパーは13.3インチと大型であることの他に、Spectra 6 (E6)という新しい技術が使われているという特徴があります。 Spectra 6は以前のカラー電子ペーパーで使われていたACePという技術と比較して、表示可能な色数は7色から6色に減りますがより高彩度の表示ができると言われています。 しかしながらWeb上ではこの電子ペーパーの画質に関する客観的な情報があまり見つからなかったので、以前のカラー電子ペーパーと画質を比べてみました。
デジカメで電子ペーパーの表示結果を撮影した場合、その画像は照明やカメラの画像処理エンジンなど様々な要素の影響を受けます。 そこで今回はカラーチャート(カラーチェッカー)を使って撮影した写真の色を補正することにしました。 色補正をするソフトは市販のものもありますが、OpenCVにColorCorrectionModelというライブラリがあるのでそれを使いました。 基本的にRGBのカラーチャンネルをアフィン変換することで色補正を行います。また画像の中からカラーチャートを自動検出することもできます。 このOpenCVのライブラリはカスタマイズ性が高いので、正確な色(Lab色空間での値)が分かっていればどのようなカラーチャートでも利用できます。 今回は、Charttu社の24色のカラーチャートを使用しました。 X-Rite社やDatacolor社のメジャーなカラーチェッカーの他に、Pantone Color Matching CardやDGK Color Calibration Chartなどいくつかの色補正用カラーチャートが存在するようです。
色補正の対象となる画像はイメージセンサーから出力された値を直接使うのが望ましく、ホワイトバランス調整やノイズ除去などの非線形な処理を行った画像に対しては色補正の精度が悪くなります。 そこで今回は、デジタル一眼カメラで撮影したRAWデータをdcrawというソフトでLinear 16 bitで現像した画像を使いました。 色補正に使用したコードはここにあります。 このページに載せた写真でカラーチャートが写っているものは、全て自然光の下で撮影して色補正を行った後の写真です(ただし縮小してJPEG圧縮してあります)。
まず最初に、7色または6色からなる単純なカラーパターンを作成して比較しました。 以下にそのカラーパターンと、画像生成に使用したコマンドを示します。
convert -size 1024x600 "xc:white" +antialias \ -draw "fill #000000 polygon 0,0, 511.5,299.5 511.5,0" \ -draw "fill #ffffff polygon 511.5,0, 511.5,299.5 1023,0" \ -draw "fill #00ff00 polygon 1023,0, 511.5,299.5 1023,299.5" \ -draw "fill #0000ff polygon 1023,299.5, 511.5,299.5 1023,599" \ -draw "fill #ff0000 polygon 1023,599, 511.5,299.5 511.5,599" \ -draw "fill #ffff00 polygon 511.5,599, 511.5,299.5 0,599" \ -draw "fill #ff7700 polygon 0,599, 511.5,299.5 0,299.5" \ pattern_lcd_1024x600.png convert -size 800x480 "xc:white" +antialias \ -draw "fill #000000 polygon 0,0, 399.5,239.5 399.5,0" \ -draw "fill #ffffff polygon 399.5,0, 399.5,239.5 799,0" \ -draw "fill #00ff00 polygon 799,0, 399.5,239.5 799,239.5" \ -draw "fill #0000ff polygon 799,239.5, 399.5,239.5 799,479" \ -draw "fill #ff0000 polygon 799,479, 399.5,239.5 399.5,479" \ -draw "fill #ffff00 polygon 399.5,479, 399.5,239.5 0,479" \ -draw "fill #ff7700 polygon 0,479, 399.5,239.5 0,239.5" \ pattern_acep_800x480.png convert -size 1600x1200 "xc:white" +antialias \ -draw "fill #000000 polygon 0,0, 799.5,599.5 799.5,0" \ -draw "fill #ffffff polygon 799.5,0, 799.5,599.5 1599,0" \ -draw "fill #00ff00 polygon 1599,0, 799.5,599.5 1599,599.5" \ -draw "fill #0000ff polygon 1599,599.5, 799.5,599.5 1599,1199" \ -draw "fill #ff0000 polygon 1599,1199, 799.5,599.5 799.5,1199" \ -draw "fill #ffff00 polygon 799.5,1199, 799.5,599.5 0,1199" \ pattern_spectra6_1600x1200.png
これらのカラーパターンを実際に表示したものを比較したのが下の写真です。
左から順に液晶ディスプレイ(7インチタブレットLenovo Tab M7 3rd Gen、画面輝度は50%)、7.3インチACePカラー電子ペーパー、13.3インチSpectra 6カラー電子ペーパーです。 さすがに液晶に比べると電子ペーパーは彩度が劣ります。
電子ペーパーの各色のRGB値とHSV値は下記の通りになりました。
色 | 純色 (RGB) | ACeP (RGB) | Spectra 6 (RGB) | 純色 (HSV) | ACeP (HSV) | Spectra 6 (HSV) |
黒 | ( 0, 0, 0) | ( 46, 67, 71) | ( 30, 27, 43) | (0 , 0, 0) | (189, 35, 27) | (251, 37, 16) |
白 | (255, 255, 255) | (176, 182, 178) | (156, 171, 169) | (0 , 0, 100) | (140, 3, 71) | (172, 8, 67) |
緑 | ( 0, 255, 0) | ( 49, 99, 75) | ( 49, 92, 77) | (120, 100, 100) | (151, 50, 38) | (159, 46, 36) |
青 | ( 0, 0, 255) | ( 54, 82, 105) | ( 35, 81, 136) | (240, 100, 100) | (207, 48, 41) | (212, 74, 53) |
赤 | (255, 0, 0) | (121, 64, 65) | (109, 26, 23) | ( 0, 100, 100) | (358, 47, 47) | ( 2, 78, 42) |
黄 | (255, 255, 0) | (151, 154, 77) | (153, 149, 23) | ( 60, 100, 100) | ( 62, 50, 60) | ( 58, 84, 60) |
橙 | (255, 127, 0) | (138, 102, 68) | N/A | ( 29, 100, 100) | ( 29, 50, 54) | N/A |
写真やRGB値で彩度を比較すると、ACePに対してSpectra 6は青と赤と黄で良くなっていますが、緑はやや悪化しています。
実際にテスト用画像を表示して比較しました。 カラー電子ペーパーでは7色あるいは6色しか表示できないので、カラーパレットとディザリングを使って表示する画像を減色する必要がありますが、ここでは以下の4つのカラーパレットを使いました。
減色に使用したスクリプトはこれ(パレットA-C)とこれ(パレットD)です。 テストに使用した画像はこちらのページの以下のものです。
そして実際に表示した結果が下の通りです。
この写真の中で、上が13.3インチSpectra 6で、左下が7.3インチACePです。 13.3インチの方には4つの画像がありますが、左上がパレットA、右上がパレットB、左下がパレットC、右下がパレットDを使った画像です。 7.3インチではパレットCを使っています。 それぞれの画像は全て800x480の同じサイズです。
13.3インチの表示例を見るとパレット毎の違いが分かります。 パレットA(純色パレット)は常に彩度が低くノイジーです。 パレットB(実際のパレット)はハイライトが飛びやすいです。 パレットC(実機サンプル画像のパレット)はどの画像でも比較的画質が安定しています。 パレットD(適応的パレット)はパレットCよりもややコントラストが高くなりますが色が変わってしまうことがあります。
13.3インチのSpectra 6 (パレットC)と7.3インチのACePを比較すると、多くの場合Spectra 6の方がやや鮮やかな結果が得られています。
以前のページで説明したように、減色で使用するカラーパレットにより画質が大きな影響を受けます。 パレットCは、元々ACePカラー電子ペーパーのサンプル画像から得たカラーパレットですが、Spectra 6でもよい結果が得られました。
回路は前回とほとんど同じ以下のとおり配線しました。
VCC | EPD:VCC |
ESP:3V3 | BAT+ |
ESP:GND | EPD:GND, BAT- |
ESP:IO23(MOSI) | EPD:DIN |
ESP:IO18(CLK) | EPD:SCK |
ESP:IO19 | EPD:CS_M |
ESP:IO22 | EPD:CS_S |
ESP:IO21 | EPD:DC |
ESP:IO17 | EPD:RST |
ESP:IO16 | EPD:BUSY |
ESP:IO4 | EPD:PWR |
ESP:IO3(RXD) | CON:RXD |
ESP:IO1(TXD) | CON:TXD |
この13.3インチをフォトフレームとして使うためにArduinoのESP32用のファームウェアを書きました。
この電子ペーパーの制御は従来のものと比べてややクセがあります。まず、コントローラーが2つあるために、チップセレクト(CS)信号が2つあります。 また電源をMOS-FETで完全に遮断するためのPWR信号が追加されていて、未使用時の消費電力をゼロにできます(Raspberry PiのGPIOピン使用時は無効)。 コマンドとデータを区別するためにD/C信号がありますが、実際には使われておらず、コマンドの直後にデータを連続して送るようになっており、その間ずっとCSをLにしておく必要があります。 また大型の電子ペーパーであるため消費電流も大きく、仕様書では最大1.4Aとなっています。そのため、単3電池2本では電圧降下のため動きませんでした。
このフォトフレームは通常はディープスリープでマイコンを停止していますが、指定したスリープ時間が経過するかタクトスイッチ(GPIO0に接続)が押されるとスリープから復帰して画像表示を行います。 また電源投入時にそのスイッチを押すことにより各種設定や画像データの転送を行うことができます。 具体的には、下記の動作モードがあります。
設定モードでは、アクセスポイントモード(親機)でHTTPサーバーを動かします. スマホやタブレットで接続して(SSIDは"ESP32"、パスワードは"12345678"、接続先は"http://192.168.0.1/")、転送モードや同期モードで使うアクセスポイントのSSID、そのパスワード、同期先、およびスリープ時間(単位は秒)を設定します。 任意のキーと値のペアを登録できるので、それぞれ"SSID"、"PASS"、"URL"、"SLEEP"というキーに対する値として登録します. 設定した値はフラッシュメモリ上に保存されます.
同期モードでは、指定したWebサーバーのディレクトリにある画像ファイルをESP32に転送して同期させます。 設定モードで"URL"のキーに対して同期先を登録しておきます。 Basic認証がある場合は"http://user:password@example.com/dir/subdir/"のように指定できます。 スラッシュで終わるディレクトリを指定します。 なおファイルサイズを参照してファイルの一致性を調べるため、ファイルを更新してもファイルサイズが変わらないと同期できません。 また、config.txtというファイルにキーと値をタブ区切りで入れておくと、設定モードと同様にキー値に対する値を登録できます。 画像を置いておくディレクトリには、ファイル一覧を得られるようにするため以下の内容で.htaccessとindex.cgiファイルも置いておく必要があります。
[.htaccess] Options +ExecCGI AddHandler cgi-script .cgi [index.cgi] #!/bin/sh echo "Content-Type: text/plain" echo "" find . -maxdepth 1 -name "*.gif" -printf '%s %f\n'
転送モードでは、ステーションモード(子機)でアクセスポイントに接続してFTPサーバーを動かします. 適当なFTPクライアントソフトで接続して、画像ファイルのアップロードや削除を行います. WindowsであればファイルエクスプローラーをFTPクライアントとして使えます。 ESP32のデータ領域のフラッシュメモリは、LittleFSをファイルシステムに使いファイルを管理しました. フォトフレームで表示させる画像ファイルは全てルートディレクトリに置きます. ArduinoのSimpleFTPServerというライブラリを使用しました(SPIFFSではなくLittleFSを使うため、FtpServerKey.hのDEFAULT_STORAGE_TYPE_ESP32をSTORAGE_SPIFFSからSTORAGE_LITTLEFSに変更します)。
画像データはGIFフォーマットで格納し、以前自作したGIFデコーダーを使います。 今回の電子ペーパーは表示領域の左右それぞれにコントローラーが割り当てられて別々に転送を行う必要があるため、事前に1200x1600の画像を左右に分割して縦につなげた600x3200の画像に変換しておきます。 ファイルサイズは画像にもよりますが、250〜450KB程度でした。