【Raspberry Pi】カメラ画像をマトリックスLEDにリアルタイムに表示してみた

【ラズパイ】カメラからの画像をマトリックスLEDにリアルタイムで表示する

こんにちは! けい(Twitter)です。

今回は、ラズパイでカメラから取得した画像をマトリックスLEDにリアルタイムで映す方法についてまとめていきたいと思います。

なんとなくやってみたら、Twitterでプチバズりしてある程度の需要はあるのかな?と思っているので、いつもより少し気合が入っています(笑)。

必要な物

ラズパイ

webカメラ

ラズパイ用のカメラモジュールでも出来ますが、接続するのが面倒だったのでwebカメラで動作させました。

マトリックスLED

aliexpressで一枚1600円ものを買いました。リンク

マトリックスLEDは中国サイトで買うのが品ぞろえもコスパもいいと思います。

スイッチング電源

マトリックスLEDの消費電力が大きいので、5Vを出力できるスイッチング電源を用意しました。

スイッチング電源入力端子

スイッチング電源にコンセントからAC100Vを供給するためのコードです。

配線 & ライブラリのインストール

ここら辺は前回の記事と全く同じ内容なので、そちらを参照してください。
今回はマトリックスLEDを1枚だけ使います。

配線でのトラブルが起きることが多いので、前回の記事のデモが動作するのを確認してからこの先を進むと良いと思います。

また、前回の記事でライブラリをダウンロードした前提で進めていきますので、そちらもお願いします。

pythonライブラリのインストール

マトリックスLEDの制御ライブラリ

前回は「rpi-rgb-led-matrix」というライブラリを用いて、コマンドでマトリックスLEDを制御しました。
しかし、今回はカメラの画像の情報を使いたいのでPythonでプログラムを書きます。
(本当はシェルスクリプトで書きたかったけど、リアルタイム性に欠けたのでPythonにしました)

それでは、Pythonライブラリのインストール作業を行います。
下記コマンドをターミナルで実行します。(rpi-rgb-matrixのダウンロード前提)

sudo apt-get update && sudo apt-get install python3-dev python3-pillow -y
cd ~/rpi-rgb-led-matrix/bindings/python
make build-python PYTHON=$(which python3) 
sudo make install-python PYTHON=$(which python3)

OpenCVのインストール

Pythonで画像を取り扱うにあたって、私が愛用しているOpenCVを使います。

インストール作業は少し面倒ですが、OpenCVは便利なのでぜひ使っていただきたいです。

まずはアップデートとpipのアップグレードを行います。

sudo apt update
sudo apt upgrade
sudo pip install --upgrade pip

依存ライブラリのインストールを行います。

sudo apt install libavutil56 libcairo-gobject2 libgtk-3-0 libqtgui4 libpango-1.0-0 libqtcore4 libavcodec58 libcairo2 libswscale5 libtiff5 libqt4-test libatk1.0-0 libavformat58 libgdk-pixbuf2.0-0 libilmbase23 libjasper1 libopenexr23 libpangocairo-1.0-0 libwebp6

opencv-pythonのインストールを行います。

sudo pip3 install opencv-python

これで通常インストールが成功すると思いますが、importするときにエラーになることがあるようです。

「sudo pip3 install opencv-python」というコマンドを実行すると、最新版のOpenCVがインストールされます。

そこで、以前のバージョンを指定してインストールすることで上手くいくことがあるようです。参考

ここのURLから、現在リリースされているopencv-pythonのバージョンを確認することができます。

現在(2021/05/26)の最新版は「4.5.2.52」です。
1つ前のバージョン「4.5.1.48」を指定してインストールしたい場合は、

sudo pip3 install opencv-python==4.5.1.48

を実行します。

プログラム

マトリックスLEDにカメラ画像をリアルタイムで映すプログラムです。

import numpy as np
import cv2
from rgbmatrix import RGBMatrix, RGBMatrixOptions
from PIL import Image
import time

cap = cv2.VideoCapture(-1)

## matrixLED オプション設定
options = RGBMatrixOptions()
options.rows = 32
options.cols = 64
options.chain_length = 1
options.parallel = 1
# options.hardware_mapping = 'regular'  # If you have an Adafruit HAT: 'adafruit-hat'
options.disable_hardware_pulsing = 1
options.gpio_slowdown = 5
# options.brightness = 70
# options.limit_refresh_rate_hz = 200
# options.show_refresh_rate = 50
# options.pwm_lsb_nanoseconds = 350

matrix = RGBMatrix(options = options)

# トリミング 設定
x,y = 8, 0
w,h = 32, 64

def cv2pil(image):
    ''' OpenCV型 -> PIL型 '''
    new_image = image.copy()
    if new_image.ndim == 2:  # モノクロ
        pass
    elif new_image.shape[2] == 3:  # カラー
        new_image = new_image[:, :, ::-1]
    elif new_image.shape[2] == 4:  # 透過
        new_image = new_image[:, :, [2, 1, 0, 3]]
    new_image = Image.fromarray(new_image)
    return new_image

try:
    while(True):
        ret, frame = cap.read()
        height, width, channels = frame.shape[:3]
        print('original image : ' + str(width) + 'x' + str(height))
        frame2 = cv2.resize(frame, (64,48))  # 縮小 640x480 > 64x48
        frame3 = frame2[x:x+w, y:y+h]        # トリミング 64x48 > 64x32
        image = cv2pil(frame3)
        matrix.SetImage(image.convert('RGB'))
        
except KeyboardInterrupt:
    cap.release()

プログラム解説

オプション設定(10~21行目)

マトリックスLEDを綺麗に光らせるために重要な項目です。

ここは何度もプログラムを実行してみて、最適なパラメーターを見つけて下さい。

画像のちらつきがある場合は、「options.gpio_slowdown」という項目をいじれば結構改善されました。

どんなオプションがあるかはここから見れます。

画像の縮小&トリミング

画像をマトリックスLEDで表示するためには、マトリックスLEDのピクセル数に合わせる必要があります。

今回私は、64×32のマトリックスLEDを使ったので、取り込んだ画像を最終的にそのサイズに変更する必要があります。

そこでまず取り込んだ画像(640×480)を縮小し、64×48にします。つまり1/10に縮小しています。

次に、これを64×32にトリミングしています。つまり高さを16行分削っています。

これはお使いのwebカメラが取り込む画像サイズによって変わるので、print文で出力された画像サイズを元にプログラムを調整してください。

PIL画像形式への変換

使用しているライブラリがPIL形式での画像が必要なため、29~39行目の関数を使って最終的な画像の形式をPIL形式に変換しています。

個々の部分のプログラムは次のサイトから拝借しました。参考url

動作結果