はじめに
今までは、AIでの画像処理について説明してきました。
実際にAIを使用するには、OpenCV で USBカメラ や 画像を読み込んで処理する必要があります。
いつも処理方法をググっていましたが、せっかくなのでブログにベースプログラムを用意して、追加していこうと思い、この記事を始めました。
前提条件
前提条件は特にありません。
私の動作環境は以下の通りです。
- Python == 3.9.13
- opencv-python == 4.6.0
- numpy == 1.23.4
- Windows11
使用する USBカメラ は ELECOM の UCAM-C310FBBK です。特に何でもいいです。
ベースとなるコード
コードの作成
まず始めに、作業用フォルダを作成します。
cd ~/
mkdir opencv-tips
cd opencv-tips
code .
VSCode 上で opencv-tips フォルダを開き、base_capture.py を作成してください。
base_capture.py に以下のコードを記述してください。
import cv2
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if ret:
cv2.imshow("window name", frame)
lastkey = cv2.waitKey(1)
if lastkey == ord("q"):
cap.release()
cv2.destroyAllWindows()
break
コードの説明をします。
import cv2
cap = cv2.VideoCapture(0)
cv2.VideoCapture(0) は、ビデオキャプチャクラスを cap という変数にインスタンス化します。
USBカメラは挿した順に PC に認識されるので、引数の 0 は、カメラの番号と考えてください。
内蔵カメラのノートPCを使用している場合、USBカメラの番号は 1 なので、
cv2.VideoCapture(1) となります。
ret, frame = cap.read()
if ret:
cv2.imshow("window name", frame)
cap.read() は、USBカメラから 1フレーム を読み込みます。
返り値は、ret, frame : 読み込めたかどうか(bool), 画像(numpy.ndarray) となります。
cv2.imshow(“window name”, frame) は画像を表示する関数です。
異なる画像を並べて表示したいときは、 window name を分ける必要があります。
lastkey = cv2.waitKey(1)
if lastkey == ord("q"):
cap.release()
cv2.destroyAllWindows()
break
cv2.waitKey(1) は 1 ミリ秒のキー入力を受け付ける関数です。
1000 にすると、1秒 です。0 にすると、キー入力があるまで待機します。
残りの部分はテンプレートとして覚えておいてください。
q を押したら終了するプログラムです。
実際に動かしてみる
それでは、実際に動かしてみましょう。
python base_capture.py
1分程度経過した後、カメラの映像が表示されます。この現象、Linux では起きないのですが、Windowsでは発生してしまいます。
Windows で USBカメラ の起動が遅い問題
USBカメラの起動が遅いので、早くしようと思います。
cap = cv2.VideoCapture(0)
↓
cap = cv2.VideoCapture(1, cv2.CAP_DSHOW)
上記のように変更してください。Direct Show バックエンドを使用してキャプチャします。
これを指定しないと、自動認識で、ほとんどの場合 FFMPEG が選択されるはずです。
詳細は公式サイトの VideoCaptureAPIs をご参照ください。
変更したら、再度プログラムを動かしてみてください。
python base_capture.py
明らかに起動の速さが変わったと思います。
画像を保存する
続いて、キーボードの c を押すと画像を保存するプログラムに変更します。
if lastkey == ord("q"):
cap.release()
cv2.destroyAllWindows()
break
if lastkey == ord("c"):
cv2.imwrite("frame.png", frame)
上記に変更して実行し、映像上でクリックしてから c を押してください。
すると、opencv-tips フォルダ内に frame.png が保存されているはずです。
このままでは、連続撮影をすると、最新の映像が frame.png に保存されるだけです。
この対策として、
import cv2
cap = cv2.VideoCapture(1, cv2.CAP_DSHOW)
i = 0
while True:
ret, frame = cap.read()
if ret:
cv2.imshow("window name", frame)
lastkey = cv2.waitKey(1)
if lastkey == ord("q"):
cap.release()
cv2.destroyAllWindows()
break
if lastkey == ord("c"):
cv2.imwrite("frame_" + str(i) + ".png", frame)
i += 1
このように変更します。
これで、押した回数だけ連番で画像が保存されるようになりました。
カメラパラメータの調整
カメラのパラメータを調整していきます。
調整できるパラメータはカメラによりますので、是非お手元のカメラでお試しください。
詳細は公式サイトの VideoCaptureProperties をご覧ください。
import cv2
cap = cv2.VideoCapture(1, cv2.CAP_DSHOW)
i = 0
cap.set(cv2.CAP_PROP_SETTINGS, 0)
while True:
ret, frame = cap.read()
if ret:
cv2.imshow("window name", frame)
lastkey = cv2.waitKey(1)
if lastkey == ord("q"):
cap.release()
cv2.destroyAllWindows()
break
if lastkey == ord("c"):
cv2.imwrite("frame_" + str(i) + ".png", frame)
i += 1
cap.set(cv2.CAP_PROP_SETTINGS, 0) を追加しました。
早速、プログラムを動かしてみましょう。
上記のような画面が表示されるはずです。左側の画像の調整タブは 映り の調整ができます。
右側のカメラ制御タブは カメラの制御パラメータ の調整ができます。
ロジクールの C925e や C1000eR であれば、ほとんどすべての設定が可能です。
今回は非常に安価なカメラなので、調整項目が少ないです。
色々いじってみて、映像を確認してみてください。
カメラパラメータをプログラムで指定する
cap.set(cv2.CAP_PROP_SETTINGS, 0) で、カメラの調整をしました。
このパラメータを覚えておいて、プログラムで指定してやります。
項目は、以下の通りです。
- cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) … 映像の幅を調整。カメラが対応可能な幅のみ設定可能
- cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) … 映像の高さを調整。カメラが対応可能な高さのみ設定可能
- cap.set(cv2.CAP_PROP_FPS, 30) … 映像のフレームレートを調整。カメラが対応可能なフレームレートのみ設定可能
- cap.set(cv2.CAP_PROP_BRIGHTNESS, xxx) … 明るさの数値を xxx に設定
- cap.set(cv2.CAP_PROP_CONTRAST, xxx) … コントラストを xxx に設定
- cap.set(cv2.CAP_PROP_SATURATION, xxx) … 彩度、鮮やかさの数値を xxx に設定
- cap.set(cv2.CAP_PROP_HUE, xxx) … 色合いの値を xxx に設定
- cap.set(cv2.CAP_PROP_GAIN, xxx) … ゲインを xxx に設定
- cap.set(cv2.CAP_PROP_SHARPNESS, xxx) … 鮮明度の値を xxx に設定
フォーカスや露光の調整とその結果は改めてまとめておきます。
おわりに
短いですが以上で区切りとさせていただきます。
次回、フォーカスや露光の調整をしていきます。カメラをアップグレードしておきます。
コメント