ラズパイにカメラモジュールにセットしてPythonで写真や動画を撮る

ラズパイのカメラモジュールを触ってみました。
2023.05.08

最近IoTカメラに興味があり、ラズパイでもカメラを扱ってみたいと思っていました。そこで見つけたのがFreenove FNK0056です。

ラズパイ公式のカメラモジュールがあることは知っていたのですが、お値段が3倍ぐらい違います。お値打ち価格に心を惹かれ「やってみる」の精神で試してみることにしました。

なおマニュアルがGitHubで公開されているので、気になった人は覗いてみるといいと思います。

セットアップ

ラズパイ

Raspberry Pi 3 Model Bを使いました。OSは「Raspberry Pi OS Full (64-bit)」です。

OSの詳細はこちら。

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Debian
Description:	Debian GNU/Linux 11 (bullseye)
Release:	11
Codename:	bullseye

また、VNCでMac Book Proから接続しています。

Freenove FNK0056

YouTubeにセットアップ動画が上がってるのでこれに従って準備します。特に困った点はありませんでした。

我が家では以下のような形になりました。ちなみにケースはこちらのものです。

やってみる

GitHubに上がっているチュートリアルに従って触っていきます。チュートリアルにはラズパイ用とJetson Nano用があるので間違わないようにします。

ターミナルからカメラを動かす

Hello World的なコマンドであるlibcamera-helloを試します。

libcamera-helloは、カメラ用の「hello world」アプリケーションに相当するものです。カメラを起動し、プレビュー・ウィンドウを表示し、それ以外は何もしません。例えばlibcamera-helloは、約5秒間プレビューウィンドウが表示されるはずです。

ラズパイ公式ドキュメントを翻訳して引用

ただし、1つ注意点があります。

libcamera-apps は、Pi 0 から 3 のデバイスで最新の Bullseye イメージを実行すると、正しく動作しません。 回避策としては、ターミナルを開き、"sudo raspi-config "を実行し、"Advanced Options "に移動し、以下を有効にします。"Glamor "グラフィックアクセラレーションを使用します。その後、Piを再起動します。

チュートリアルを翻訳して引用

今回使っているラズパイのモデルが3B、OSもBullseyeということで回避策を行いました。チュートリアルには図も含まれているので特に迷うこともありませんでした。 

ターミナルから以下のコマンドを実行してみます。

libcamera-hello

数秒間プレビューウィンドウが表示されました。

Pythonで写真撮影

ここからはRaspberry Pi OSにデフォルトで入っているPython IDEであるThonnyでコードを書いていきます。また、カメラを制御するのにはPiCamera2というライブラリを使います。

以下のコードを実行します。

from picamera2 import Picamera2, Preview
import time

picam2 = Picamera2()
camera_config = picam2.create_preview_configuration()
picam2.configure(camera_config)
picam2.start_preview(Preview.QTGL)
picam2.start()
time.sleep(2)
picam2.capture_file("test.jpg")
picam2.close()

実行してみます。プレビューウィンドウが表示され、2秒後にキャプチャが撮られます。

プレビューの設定を変更することもできます。より変化がわかりやすいようにチュートリアルのコードに少し手を加えて、画像を回転してみます。

from picamera2 import Picamera2, Preview
from libcamera import Transform

picam2 = Picamera2()
picam2.start_preview(Preview.QTGL, x=100, y=200, width=800, height=600,
transform=Transform(hflip=1, vflip=1))
picam2.start()

Pythonで動画撮影

次は動画です。H.264形式で撮影します。

Picamera2では、ビデオのキャプチャとエンコードのプロセスはほぼ自動化されています。アプリケーションは、画像データの圧縮に使用するエンコーダと、圧縮されたデータストリームの出力方法を定義するだけです。

チュートリアルを翻訳して引用

from picamera2.encoders import H264Encoder
from picamera2 import Picamera2
import time

picam2 = Picamera2()
video_config = picam2.create_video_configuration()
picam2.configure(video_config)
encoder = H264Encoder(bitrate=10000000)
output = "test.h264"
picam2.start_recording(encoder, output)
time.sleep(10)
picam2.stop_recording()

このような動画が撮れました。

次は1つのスクリプトの中でビットレートを3段階で変えながら動画を撮ってみます。

import time
from picamera2.encoders import H264Encoder, Quality
from picamera2 import Picamera2

picam2 = Picamera2()
video_config = picam2.create_video_configuration()
picam2.configure(video_config)

low_encoder = H264Encoder(bitrate=1000000)
picam2.start_recording(low_encoder, 'low.h264')
time.sleep(5)
picam2.stop_recording()

medium_encoder = H264Encoder(bitrate=5000000)
picam2.start_recording(medium_encoder, 'medium.h264')
time.sleep(5)
picam2.stop_recording()

high_encoder = H264Encoder(bitrate=10000000)
picam2.start_recording(high_encoder, 'high.h264')
time.sleep(5)
picam2.stop_recording()

マニュアルではpicam2.start_recordingの"quality"という引数を指定する方式でしたが、撮影した動画に違いが見られず、実装の調査を行ったところ、この引数は機能していないことが分かりました(2023.5.2現在)。本件はPicamera2のIssueとして起票しているので、詳細はこちらをご覧ください。

以下の3つの動画が得られました。特に1つめの低ビットレートでは顕著に画質の違いがあることが分かります。

ファイルサイズにも差が出ていますね。

$ ls -ltr
合計 7436

-rw-r--r-- 1 pi pi  589947  5月  2 17:14 low.h264
-rw-r--r-- 1 pi pi 3066060  5月  2 17:14 medium.h264
-rw-r--r-- 1 pi pi 3950489  5月  2 17:14 high.h264

おわりに

今回はFreenoveのカメラモジュールをラズパイにセットアップしました。

ハードウェア、ということで身構えていたものの、動かすだけであれば思ったよりも簡単でした。特にPythonのコードがあることでどんな処理を行っているのか分かりやすくてよかったです。

一方で、より深く触っていくのであればカメラや写真、動画といったものに対する知識も必要になってくるように思いました。このあたりもキャッチアップしていきたいと思います。