静止画を撮影する 【OpenCV】

Raspberry Pi

Raspberry Pi や Windows パソコンなどで、USB カメラ等を接続して静止画を撮影する Python のスクリプトをまとめておきます。
具体的には、Raspberry Pi などに USB カメラを接続しておきます。スクリプトで OpenCV の機能を用いてライブ画像を表示し、キーボード操作により撮影します。
以下の2つの環境で動作確認をしています。

環境1: Raspberry Pi (buster、および、bullseye)、USB カメラ、OpenCV インストール済み(Python 3 で動作確認済み)
環境2: Windows パソコン

背景 ~ USB カメラの有効活用!

USB カメラを複数持っていますが、とっさに写真を撮影したくなることがあります。(急に雪が降ってきて風景を撮りたいときなど。)

このとき、USB カメラがたまたま Windows パソコンにつないであった場合、Windows 標準のカメラアプリを使うことで、静止画などをすぐに撮影することが可能です。
ところが、USB カメラが Raspberry Pi につないであったとき、同じような標準アプリがあるとよいのですが見当たりません。
そこで、簡単に静止画を取得する Python のスクリプトについてまとめておきます。

すぐに使える機能をスクリプト化してそろえておくと、後から修正や改善、組み合わせ、自動化が自由自在となります。カスタマイズにより活用の幅が格段に広がります。
以下は、Raspberry Pi (Linux)を想定して記載していますが、動作確認をしてみたところ、Windows パソコンでもスクリプトがそのまま動きました。

設定方法

事前準備: OpenCV のインストール & カメラの「有効」設定

※ 事前に OpenCV のインストールを済ませておく必要があります。インストールしていない場合は、末尾の関連リンクを参照してください。

※ また、Raspberry Pi 上でカメラの設定を有効にしておく必要があります。以下の手順を参考にしてください。
・ 画面左上のラズパイのマークをクリック → 「設定」→「Raspberry Pi の設定」をクリックする。
→ 「インターフェイス」タブを選択 → カメラの欄で「有効」を選択 → 「OK」ボタンをクリックする。
→ 再起動を促す表示に従って、Raspberry Pi を再起動したら、完了です。

撮影用のスクリプトの設定

① 以下を例に、Raspberry Pi に画像保存用のフォルダを作成してください。
/home/pi/camera1/
② 上のフォルダの中に、camera1.py 等の名前でテキストファイルを作成し、下記のサンプルスクリプトをコピー&ペーストして保存してください。
★ 接続しているカメラ(カメラ番号)は、スクリプトの冒頭で cv2.VideoCapture(0) の “0” の数値で指定しています。
以下でスクリプトを実行したとき、カメラから画像が取得できない場合や、カメラが複数つながっている場合は、この数値 “0” を “1”, “2” 等に変更して、接続しているカメラ/使いたいカメラ(カメラ番号)を指定してください。

使い方

③ 事前に、Raspberry Pi (または Windows パソコン)にカメラを接続しておきます。
USB カメラで動作確認をしていますが、Raspberry Pi 標準のカメラでも動作すると思います。
④ ターミナルを起動し、以下を参考にスクリプトを実行してください。
python3 /home/pi/camera1/camera1.py
→ ライブ画像が表示されます。

★ 必要により、ライブ画像を確認し、USB カメラのピント合わせ、位置合わせをしてください。
★ なお、①、②でフォルダの場所やスクリプトのファイル名を変えた場合は、対応するように修正してください。
★ OpenCV を動かしてみて、もし、”RuntimeError: module compiled against API version 0xf but this version of numpy is 0xd” といったエラーが出るようでしたら、”pip install numpy –upgrade” を実行し、numpy をアップグレードしてみてください。私の環境では、エラーが解消されました。

⑤ キーボードの “c” キーを押すと、①のフォルダ内に、画像データを日付つきのファイル名として JPG 形式で保存します。
⑥ ”q” キー、または、[esc] キーを押すと、スクリプトを終了します。

うまく動いたら

・ コマンドで動きますので、Linux を使っている場合、Linux の cron 機能を使って、自動撮影も可能となります。
この場合、カメラのオートゲインなどが働くと思いますので、一定のフレーム数分、ライブでカメラを動かしておいて明るさ調整が安定したあたりで1ショット撮影するようスクリプトを修正すると動くと思います。
・ 最も簡単なスクリプトとしましたが、スクリプトを修正していくことで、ほかにも、ライブの動画を保存したり、画像処理を追加することも可能です。
・ ライブ画像の表示中に、キーボードの任意のキーを押すと、そのコードが出力されるようにしています。現在は1ショット撮影とプログラムの停止機能のみを入れていますが、必要により機能を追加してアレンジしてみてください。

・ なお、ご参考までに、動作確認をしているカメラを末尾の関連リンクに貼っておきます。
★ このサイトに記載しているような技術的な検討をされる場合は、固定フォーカスやオートフォーカスのタイプよりは、手動でピント合わせができるマニュアルフォーカスのタイプをおすすめします。固定フォーカスでは、バーコードのように近づけて解像度を上げて読み取りたいときに調整が難しくなるため、また、オートフォーカスでは自動化しようとして1ショットで撮影を成功させたいとき、ピント合わせに失敗する可能性が生じるためです。

まとめ

基本的なところかなとも思いますが、Raspberry Pi などで USB カメラなどのライブ画像を表示して画像を取得するスクリプトをまとめました。

他にも、USB カメラを使った画像認識などについて、サンプルスクリプトをまとめています。もし、関心があるようでしたら関連リンクなども参照してみてください。

関連リンク
・ 動作確認済み USB カメラ 【おすすめ】
・ 起動用SDカードを設定する 【Raspberry Pi】
・ 初期設定のまとめ 【OpenCV & Raspberry Pi】
・ 接続中のカメラ番号を抽出する 【OpenCV & Python】
・ OpenCV でライブ画像表示 【Python】
・ 顔認識ソフトウェア 【Python & OpenCV】
・ フルーツでの物体検出をやってみた 【YOLOv5】
・ ウェブサイトのスクリーンショットを撮る 【Windows 版】

サンプルコード camera1.py

import cv2
import datetime as dt1 
import os 

cap1 = cv2.VideoCapture(0)
path1 = os.path.dirname(__file__) + "/" 

while True:
    ret1, frame1 = cap1.read()
    if ret1:
        cv2.imshow( "Frame", frame1 )
        key1 = cv2.waitKey(1) 
        if key1 == ord('q') or key1 == 27: 
            break
        elif key1 == ord('c'): 
            today1 = dt1.datetime.today() 
            file0 = "{:%y%m%d_%H%M%S}".format(today1) + ".jpg" 
            file1 = path1 + file0
            print( file1 ) 
            cv2.imwrite( file1, frame1 ) 
        elif key1 > -1: 
            print( key1 ) 
    else: 
        break 

cap1.release()
cv2.destroyAllWindows()

タイトルとURLをコピーしました