FRDM-IMX95ボードを使って、カメラを使うアプリケーションの導入部分を2つご紹介します。
厳密にはどちらもGstreamerを使うのですが、後者は取得した画像フレームごとにAIモデルに入力させるようなユースケースへの土台にもなります。
(作業時間:10分) *LinuxイメージがFRDM-IMX95に書き込めている前提
FRDM-IMX95の使用方法はFRDM-IMX95 Board User Manualをご参照ください。
自身でビルドしたイメージファイルを使って頂いてもOKです。その場合はimx-image-fullをお使いください。
[入門] Yocto Linux BSPのビルド方法 - i.MX FRDMボード編 (日本語ブログ)も参考にしてください。イメージを書き込む手順は、Linux BSPをビルドして生成したイメージをターゲットボードに書き込む方法の「4.2.2. uuuでの書き込み - wicイメージ全体の書き込み」をご参照ください。
u-bootのコンソールで、以下のように実行します。
これはOS08A20カメラモジュールをLinuxに認識させるためのデバイスツリー設定です。
u-boot=> setenv fdtfile imx95-15x15-frdm-os08a20-isp.dtb
u-boot=> saveenv
i.MX 95はlibcameraというフレームワークを使っています。cam -lコマンドで、ハードウェアが正しく接続されているか、また設定されているデバイスツリーが正しいかが確認できます。以下が期待値です。
root@imx95-15x15-lpddr4x-frdm:~# cam -l
[0:27:23.440218928] [901] INFO Camera camera_manager.cpp:340 libcamera v0.0.0+6489-lf-6.18.2-1.0.0
[0:27:23.544276996] [902] INFO MediaPipeline media_pipeline.cpp:240 Found pipeline: [os08a20 3-0036|0] -> [0|csidev-4ad30000.csi|1] -> [0|4ac10000.syscon:formatter@20|1] -> [2|crossbar]
[0:27:23.545335314] [902] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc/bus@42000000/i2c@42540000/os08a20_mipi@36' for pipeline handler imx8-isi
Available cameras:
1: External camera 'os08a20' (/base/soc/bus@42000000/i2c@42540000/os08a20_mipi@36)
最後の行に表示されるもの(/base/soc/bus@42000000/i2c@42540000/os08a20_mipi@36)を、後ほどカメラ名として使用します。
以下の2行を実施し、適切な環境変数を設定します。
root@imx95-15x15-lpddr4x-frdm:~# export LIBCAMERA_IPA_MODULE_PATH="/usr/lib/libcamera/ipa"
root@imx95-15x15-lpddr4x-frdm:~# export LIBCAMERA_PIPELINES_MATCH_LIST="nxp/neo,imx8-isi,uvc"
次に以下コマンド2つで、HDMI接続されたディスプレイにカメラのプレビュー表示がされるはずです。
root@imx95-15x15-lpddr4x-frdm:~# CAMERA0=/base/soc/bus@42000000/i2c@42540000/os08a20_mipi@36
root@imx95-15x15-lpddr4x-frdm:~# gst-launch-1.0 libcamerasrc camera-name="${CAMERA0}" ! \
video/x-raw, width=3840,height=2160,framerate=30/1,format=YUY2 ! \
queue ! \
waylandsink
最初の行で、”CAMERA0”という変数を定義し、Linux起動後にcam -lコマンドで調べたカメラの名前(パス)を指定します。それをGstreamer(gst-launch-1.0)のlibcamerasrcというプラグインに対し、camera-nameとして渡し、どのカメラを使うのかを指定しています。複数カメラがある場合は、このようにしてカメラを指定することができます。CAMERA0という変数を設定せずに、そのままcamera-nameに渡してもOKです。
次に以下のテキストファイルを作り、run-opencv.pyとして保存しておきます。
import os
import cv2
os.environ["LIBCAMERA_IPA_MODULE_PATH"] = "/usr/lib/libcamera/ipa-nxp-neo-uguzzi/"
os.environ["LIBCAMERA_PIPELINES_MATCH_LIST"] = "nxp/neo,imx8-isi,uvc"
CAMERANAME = r"/base/soc/bus@42000000/i2c@42540000/os08a20_mipi@36"
pipeline = (
f'libcamerasrc camera-name="{CAMERANAME}" ! '
'video/x-raw,width=3840,height=2160,framerate=30/1,format=YUY2 ! '
'imxvideoconvert_g2d ! '
'video/x-raw,width=1280,height=720,framerate=30/1,format=BGRA ! '
'appsink drop=true max-buffers=1'
)
cap = cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)
if not cap.isOpened():
print("cannot open camera")
exit()
while True:
ret, frame = cap.read()
if not ret:
break
# BGRA -> BGR に変.してから処理
frame_bgr = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)
# エッジ強調処理
gray = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2GRAY)
laplacian = cv2.Laplacian(gray, cv2.CV_64F, ksize=5)
edge = cv2.convertScaleAbs(laplacian)
edge_bgr = cv2.cvtColor(edge, cv2.COLOR_GRAY2BGR)
result = cv2.addWeighted(frame_bgr, 1.0, edge_bgr, 0.5, 0)
cv2.imshow('Edge Enhanced', result)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
これを実行するには以下を実行します。
python3 run-opencv.py
このサンプルでは、PythonでOpenCVのAPIを使って動かしています。OpenCVにはGsteamerのパイプラインからデータを受け取る仕組みがあり、それを活用しています。
のように、pipelineでGstmeamerのパイプラインを構成しています。
リサイズの目的は、後段でのCPU処理負荷軽減によるフレームレート向上、
フォーマット変換の目的は、OpenCVが使えるフォーマットであるBGRへの変換です。
これらを2D GPUで実施し、CPU負荷を下げています。簡易的にパイプラインを図示すると以下のようになります。
こちらはフレーム単位の処理です。Gstmeamerで設定したパイプラインから1枚のフレームを受け取り、後段でのエッジ強調処理に渡しています。
このように、libcamerasrc(MIPI-CSI+ISP)→imxvideoconvert_g2d(GPU 2D)というSoCのハードウェアに大きく依存した前段をGstreamerで実施し、後段ではCPU/OpenCVによるエッジ強調といった2つに分けたような処理になっています。cap.read()でフレーム単位で画像を取り出せるので、その後の処理はやり易くなりますね。
FRDM-IMX95ボードを使って、カメラを使うアプリケーションの導入部分を2つご紹介しました。
取得した画像フレームをAIモデルに入力させるようなユースケースは別の記事で紹介させていただきます。
※この記事には、AI生成コードをベースに投稿者が内容を確認した内容が含まれます。
=========================
本投稿の「Comment」欄にコメントをいただいても、現在返信に対応しておりません。
お手数をおかけしますが、お問い合わせの際には「NXPへの技術質問 - 問い合わせ方法 (日本語ブログ)」をご参照ください。
(既に弊社NXP代理店、もしくはNXPとお付き合いのある方は、直接担当者へご質問いただいてもかまいません。)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.