Raspberry Pi カメラモジュールV3をPython OpenCVで操作する方法

【PR】この記事には広告が含まれています。

Raspberry Pi カメラモジュールV3をPython OpenCVで操作する方法

ラズベリーパイの代表的なオプションパーツであるカメラモジュール。Raspberry Pi財団からオートフォーカス機能が搭載されたカメラモジュール V3が発売されました。

画素数も800万画素から1200万画素になり、HDR(High Dynamic Range)モードも利用できます。性能が大幅にアップしているのにもかかわらず、価格は従来のモデルからあまり変わっていない点も要注目です。


Camera Module 2

Camera Module 3
画素数800万画素
(3280 × 2464) 
1200万画素
(4608 x 2592)
センサーSony IMX219Sony IMX708
フォーカス手動調節式
(固定フォーカス)
モーター駆動
(オートフォーカス)
HDR対応なしあり
価格
KSY
4,070円4,400円
詳細詳細を見る詳細を見る

発売後すぐに購入したCamera Module 3。先代のV2と設定や操作方法が異なり、思いのほか苦労しました。

チェックポイント

この記事ではPythonのプログラムからカメラモジュール V3を操作する方法をまとめています。

公式のプロモーション動画はこちらからご覧いただけます。

使用準備

環境の確認

今回、動作確認で使用した環境は以下の通りです。

OSのバージョンは以下のコマンドで確認できます。

lsb_release -a

カメラモジュールの接続

  1. 黒いロックを持ち上げる。
  2. リボンケーブルを挿入する
  3. ロックを下に押し込んで固定する

まず、カメラポートの黒いロック部分を上に持ち上げます。

カメラポートのロック解除方法
カメラ接続

リボンケーブルを差し込みます。向きに注意してください。端子部分がHDMIポート側に向くよう接続にします。

リボンケーブルの差し込み方
リボンケーブルの向き

黒いロック部分を押して固定します。

リボンケーブルのロック方法
ケーブルのロック

OSのアップグレード

カメラモジュール3はlibcameraというソフトで操作します。OSをアップグレードして、libcameraを最新の状態にします。

まずターミナルで以下のコマンドを実行して、パッケージリストを更新します。

sudo apt update

OSをアップグレード。時間がかかるので気長に待ちましょう。

sudo apt full-upgrade -y

アップグレードが完了したら再起動します。

sudo reboot

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

まず、pipを最新のバージョンにします。下記のコマンドをターミナルに入力してEnterキーを押してください。

sudo python -m pip install --upgrade pip

OpenCVをバージョン指定でインストールします。

sudo pip3 install opencv-python==4.5.1.48

numpyというライブラリをバージョン指定でインストールします。

sudo pip3 install numpy==1.23.1

picamera2というライブラリをインストールします。picamera2はPythonでlibcameraを操作するためのライブラリです。

sudo apt install python3-picamera2

「libatlas3-base」 パッケージをインストールします。

sudo apt install libatlas3-base

Raspberry Pi 3以前のモデルは追加項目あり

Raspberry Pi 3より以前に発売されたモデルを使用する場合は、追加で設定する項目があります。

  • raspi-configで「Glamor」を有効にする
  •  /boot/config.txtで「dtoverlay=vc4-kms-v3d」のコメントアウトを外す
  • /boot/config.txtの最下行に「dtoverlay=imx708」を追加

詳細は公式ドキュメントを確認ください。

Pythonプログラムで撮影する

まずは基本的な操作方法を解説します。

静止画の撮影

スタートメニューのプログラミングからThonnyを開きます。

以下のプログラムをコピーペーストします。

from picamera2 import Picamera2

picam2 = Picamera2()

#カメラ画像を保存する
picam2.start_and_capture_file("test.jpg")

プログラムを保存して実行します。

プログラムを実行すると、test.jpgというファイル名で画像が保存されます。

test.jpgという固定のファイル名にすると、撮影するたびに画像が上書きされてしまいます。そこで以下のように撮影した時刻をファイル名にすることで、過去の画像を残しつつ新しい画像を保存できます

from picamera2 import Picamera2
import datetime

# 現在の日時を取得し、ファイル名に使用する
dt_now = datetime.datetime.now()
file_name = dt_now.strftime('%Y%m%d_%H%M%S')

picam2 = Picamera2()

# カメラ画像を保存する
picam2.start_and_capture_file(file_name + '.jpg')

動画の撮影

from picamera2 import Picamera2

picam2 = Picamera2()

#5秒間の動画を撮影して保存する
picam2.start_and_record_video("test.mp4", duration=5)

上のプログラムを実行すると、test.mp4というファイル名で5秒間の動画が保存されます。

Pythonプログラムでカメラ映像(動画)を表示する

当初はOpenCVの.read()で画像を読み込もうとしたのですが、映像が表示されませんでした。そこでPicamera2を使って画像を取得してからOpenCVで表示させるという方法にしています。

import cv2
from picamera2 import Picamera2
from libcamera import controls

picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration(main={"format": 'XRGB8888', "size": (640, 480)}))
picam2.start()
#カメラを連続オートフォーカスモードにする
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})

while True:
  im = picam2.capture_array()
  cv2.imshow("Camera", im)
 
  key = cv2.waitKey(1)
  # Escキーを入力されたら画面を閉じる
  if key == 27:
    break

picam2.stop()
cv2.destroyAllWindows()

プログラムを実行するとカメラの映像が立ち上がります。オートフォーカス機能も有効になっているので、近くの映像も鮮明に撮影できます。

オートフォーカスの速度を早くしたいときは、プログラムの9行目を以下のように変更します。

picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous, "AfSpeed": controls.AfSpeedEnum.Fast})

HDR(High Dynamic Range)モードで表示する

HDR(High Dynamic Range)モードにすると、明るい部分と暗い部分がどちらも鮮明に表現できます。明るさの異なる複数枚の画像を合成して、1枚の画像を生成する仕組みです。

本来、HDRをオンにするときはコマンドを入力する必要があります。以下のプログラムではos.systemを使い、プログラム中でHDRをオンにするコマンドを実行しています

import cv2
from picamera2 import Picamera2
from libcamera import controls
import os

picam2 = Picamera2()

#HDRをオンにする
os.system("v4l2-ctl --set-ctrl wide_dynamic_range=1 -d /dev/v4l-subdev0")
print("Setting HDR to ON")

picam2.configure(picam2.create_preview_configuration(main={"format": 'XRGB8888', "size": (640, 480)}))
picam2.start()
#カメラを連続オートフォーカスモードにする
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous, "AfSpeed": controls.AfSpeedEnum.Fast})

while True:
  im = picam2.capture_array()
  cv2.imshow("Camera", im)
 
  key = cv2.waitKey(1)
  # Escキーを入力されたら画面を閉じる
  if key == 27:
    break

picam2.stop()
cv2.destroyAllWindows()

#HDRをオフにする
os.system("v4l2-ctl --set-ctrl wide_dynamic_range=0 -d /dev/v4l-subdev0")
print("Setting HDR to OFF")

参考にさせていただいたサイト
How To Use Raspberry Pi Camera Module 3 with Python Code

OpenCVを使用すれば顔認識もできる

OpenCVを使えるメリットは画像を扱うための機能が豊富に用意されていることです。顔認識もすぐに実装できます。

import cv2
from picamera2 import Picamera2
from libcamera import controls

face_detector = cv2.CascadeClassifier("/usr/local/lib/python3.9/dist-packages/cv2/data/"\
"haarcascade_frontalface_default.xml")
cv2.startWindowThread()

picam2 = Picamera2()
picam2.configure(picam2.create_preview_configuration(main={"format": 'XRGB8888', "size": (640, 480)}))
picam2.start()
#カメラを連続オートフォーカスモードにする
picam2.set_controls({"AfMode": controls.AfModeEnum.Continuous})

while True:
    im = picam2.capture_array()

    grey = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    faces = face_detector.detectMultiScale(grey, 1.1, 5)

    for (x, y, w, h) in faces:
        cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0))

    cv2.imshow("Camera", im)
   
    key = cv2.waitKey(1)
    # Escキーを入力されたら画面を閉じる
    if key == 27:
        break

picam2.stop()
cv2.destroyAllWindows()

映像の中から顔が検出されると、緑の枠で囲まれます。すみません、顔の部分は後から加工して消しています。

コメント一覧

from picamera2 import Picamera2

picam2 = Picamera2()

#カメラ画像を保存する
picam2.start_and_capture_file(“test.jpg”)
を実行すると

Camera(s) not found (Do not forget to disable legacy camera with raspi-config).Camera __init__ sequence did not complete.
とエラーが出てしまいます。

これはどう解決したらよろしいでしょうか?

返信する
そぞら

お問い合わせありがとうございます。

エラー内容を見ると、legacy cameraが有効になっている可能性が考えられます。

ターミナルで以下のコマンドを入力してraspi-configを開きます。

sudo raspi-config

メインメニューから「3 Interface Options」(インターフェイスオプション)を選択します。

インターフェイスオプションメニューから「I1 Legacy Camera」(レガシーカメラ)を選択します。

「いいえ」(無効)を選択して、レガシーカメラインターフェースを無効にします。

設定を完了した後、指示に従ってRaspberry Piを再起動します。これにより、変更が有効になります。

これで、エラーが解決しない場合は、使用しているカメラの製品名とRaspberry Piのモデル名を教えてください。

よろしくお願いいたします。

返信する

返信ありがとうございます!
こちらの問題は解決しました!ありがとうございます!
続いて恐縮なのですが、同じプログラムを実行した際に出るこれらのエラーはどうしたらいいのでしょうか?

ImportError: libopenblas.so.0: cannot open shared object file: No such file or directory

During handling of the above exception, another exception occurred:

raise ImportError(msg)
ImportError:

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the numpy C-extensions failed. This error can happen for
many reasons, often due to issues with your setup or how NumPy was
installed.

返信する
そぞら

NumPyが依存しているlibopenblas.so.0というライブラリが見つからないことが原因でNumPyが正しく動作していない可能性があります。
以下のコマンドを実行してみてください。

sudo apt update
sudo apt install libopenblas-dev

NumPy自体も再インストールが必要かもしれません。
pip install –upgrade –force-reinstall numpy

よろしくお願いいたします。

返信する
mk

コメント失礼します。
現在のnumpy(2.0.2)ではエラーが起こるため、最新のものではダメとのことです。
色々試した所、そぞらさんの監視カメラの記事から1.23.1のものでなら動作確認が取れました!

以上、linux初心者からの報告です…笑

返信する
ぐら

コメント失礼します。
いつもそぞらさんのブログを参考にさせていただいております、ぐらと申します。

こちらのサイトに書かれていた、カメラモジュールv3を使った動作は全て正常に動きました。ありがとうございます。

質問なのですが、静止画や動画を撮った際に同じ名前で保存すると、最新に撮ったものしか表示されません。そぞらさんが書かれた以下サイトにその対処法が書かれていたのですが、カメラモジュールv3でも同じプログラムを使っても良いのでしょうか?
https://sozorablog.com/camera_shooting/

なお、使用しているものは以下のとおりです。
Raspberry-Pi v4(OS:Bullseye)
Python v3.9.4
カメラモジュール v3 Noir

返信する
そぞら

ブログを読んでいただいてありがとうございます。

カメラモジュールV3の場合はcv2でカメラ映像を保存することができません。
以下のように、Picamera2で保存してみて下さい。

from picamera2 import Picamera2
import datetime

# 現在の日時を取得し、ファイル名に使用する
dt_now = datetime.datetime.now()
file_name = dt_now.strftime(‘%Y%m%d_%H%M%S’)

picam2 = Picamera2()

# カメラ画像を保存する
picam2.start_and_capture_file(file_name + ‘.jpg’)

返信する
ぐら

返信ありがとうございます。
提示していただいたプログラムを実行したところ、エラーが出ましたが、
(“%Y%m%d_%H%M%S”)と(file_name + “.jpg”)に訂正したところ、無事起動しました。
また、動画撮影の方も頂いたプログラムを参考に設定したところ、名前別で保存することができました。
ありがとうございました。

返信する
あk

先週発売開始されたSONYのAIセンサー付きのRaspberry Pi AI Cameraのレビューをお願いします!

返信する
そぞら

コメントありがとうございます。
残念ながら、AI Cameraは初回ロットを買いそびれてしまいました。
また入手したらレビューしたいと思います。

返信する

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です