Pythonでカメラを制御する【研究用】


はじめに

前回の記事
pySerialを使った顕微鏡用多波長LED光源の高速波長切り替えについて

前回は顕微鏡用多波長LED光源の制御方法について書きました。今回はPythonによるカメラ制御について書きたいと思います。顕微鏡といえば肉眼で接眼レンズをのぞき込むイメージがありますが、実はカメラで撮影する場合が多いです。バイオ分野の研究者の中には顕微鏡メーカー各社が配布しているソフトウェアや有償ソフトを購入し、使っている方もいらっしゃいます。Pythonは無償ですので手軽に始められます。また、すでに解析プログラムをPythonで書かれている方は既存のプログラムにハードウェアの制御プログラムを組み込むことで測定フローの自動化ができるでしょう。塩基配列やアミノ酸配列を扱うようなBiopythonや機械学習と組み合わせることもでき、自由度がとても広がります。
定番である画像処理モジュールOpenCVを使ってカメラから画像を取得する方法について共有できればと思います。

開発環境

  • Windows10 (x64)
  • Python 3.6
  • Anaconda 3
  • OpenCV 3.4.1

使用する機材

  • カメラ: ARTCAM-226IMX-BW-USB3-T2(Artray社)
  • PC


※図はUSB3.0 対応 CMOS カメラARTCAM-226IMX-USB3-T2 商品説明書より抜粋

OpenCVのインストール

画像処理ライブラリOpenCVを各自インストールしてください。

画像の取得

以下のプログラムを実行すると画像が取得できます。
まずはコピペして実行してみてください。

capture.py

import cv2

# VideoCapture オブジェクトを取得します
capture = cv2.VideoCapture(1)

while(True):
    ret, frame = capture.read()
    # resize the window
    windowsize = (800, 600)
    frame = cv2.resize(frame, windowsize)

    cv2.imshow('title',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

capture.release()
cv2.destroyAllWindows()

こんな風にウィンドウ上に画像が表示されます。

できない場合は、cv2.VideoCapture(1)の引数を0に変えてみてください。

ここでカメラの切り替えはcv2.VideoCapture(0)の引数で切り替えます。0が引数として設定されていますが2台目のカメラを使いたい場合はcv2.VideoCapture(1)と指定します。

画像の保存

名前と画像配列を指定して保存します。

cv2.imwrite('test.tif', image_array)

接続されているカメラの台数を数える

以下の関数のように、引数を0, 1, 2, ...と変えてあげると接続されたカメラの台数を調べられます。

capture.py
import cv2
import datetime


def check_camera_connection():
    """
    Check the connection between any camera and the PC.

    """

    print('[', datetime.datetime.now(), ']', 'searching any camera...')
    true_camera_is = []  # 空の配列を用意

    # カメラ番号を0~9まで変えて、COM_PORTに認識されているカメラを探す
    for camera_number in range(0, 10):
        cap = cv2.VideoCapture(camera_number)
        ret, frame = cap.read()

        if ret is True:
            true_camera_is.append(camera_number)
            print("camera_number", camera_number, "Find!")

        else:
            print("camera_number", camera_number, "None")
    print("接続されているカメラは", len(true_camera_is), "台です。")


if __name__ == "__main__":
    check_camera_connection()

実行結果

[ 2019-10-04 18:17:51.607549 ] searching any camera...
camera_number 0 Find!
camera_number 1 Find!
camera_number 2 None
camera_number 3 None
camera_number 4 None
camera_number 5 None
camera_number 6 None
camera_number 7 None
camera_number 8 None
camera_number 9 None
接続されているカメラは 2 台です。

カメラが2台みつかりました。
0はノートPCのインカメ、1はPCにUSB接続されているカメラです。

カメラのプロパティの取得

カメラの画素数や露光時間等の各種パラメーターを取得できる関数がOpenCVには用意されています。
cap.get()でカメラのプロパティを取得できます。

def get_camera_propaties():
    params = ['MSEC',
            'POS_FRAMES',
            'POS_AVI_RATIO',
            'FRAME_WIDTH',
            'FRAME_HEIGHT',
            'PROP_FPS',
            'PROP_FOURCC',
            'FRAME_COUNT',
            'FORMAT',
            'MODE',
            'BRIGHTNESS',
            'CONTRAST',
            'SATURATION',
            'HUE',
            'GAIN',
            'EXPOSURE',
            'CONVERT_RGB',
            'WHITE_BALANCE',
            'RECTIFICATION']

    cap = cv2.VideoCapture(1)
    for num in range(19):
        print(params[num], ':', cap.get(num))

実行結果

POS_MSEC : 0.0
POS_FRAMES : 0.0
POS_AVI_RATIO : 0.0
FRAME_WIDTH : 1280.0
FRAME_HEIGHT : 720.0
FPS : 30.0
FOURCC : 0.0
FRAME_COUNT : 0.0
FORMAT : 16.0
MODE : 0.0
BRIGHTNESS : 0.0
CONTRAST : 0.0
SATURATION : 0.0
HUE : 0.0
GAIN : 0.0
EXPOSURE : 0.0
CONVERT_RGB : 0.0
WHITE_BALANCE : 0.0
RECTIFICATION : 0.0

カメラのプロパティをPythonから設定するためには、
cap.set()関数を使います。

参考
Python, OpenCVで動画を読み込み(ファイル・カメラ映像)
https://note.nkmk.me/python-opencv-videocapture-file-camera/

設定できるかどうかはカメラの種類によって異なるため、詳しくはカメラメーカーに問い合わせていただければと思います。
パラメーターは以下の表を参考にしててください。

引数(数字)   引数(文字)   プロパティー  
0. CV_CAP_PROP_POS_MSEC     ビデオファイルの現在位置(ミリ秒)
1. CV_CAP_PROP_POS_FRAMES             次にデコード/キャプチャされるフレームの0から始まるインデックス
2. CV_CAP_PROP_POS_AVI_RATIO      ビデオファイルの相対位置
3. CV_CAP_PROP_FRAME_WIDTH        ビデオストリーム内のフレームの幅。
4. CV_CAP_PROP_FRAME_HEIGHT  ビデオストリーム内のフレームの高さ
5. CV_CAP_PROP_FPS フレームレート
6. CV_CAP_PROP_FOURCC コーデックの4文字のコード
7. CV_CAP_PROP_FRAME_COUNT ビデオファイルのフレーム数
8. CV_CAP_PROP_FORMAT retrieve()によって返されるMatオブジェクトのフォーマット
9. CV_CAP_PROP_MODE 現在のキャプチャモードを示すバックエンド固有の値
10. CV_CAP_PROP_BRIGHTNESS 画像の明るさ(カメラのみ)
11. CV_CAP_PROP_CONTRAST 画像のコントラスト(カメラのみ)
12. CV_CAP_PROP_SATURATION 画像の彩度(カメラのみ)
13. CV_CAP_PROP_HUE 画像の色相(カメラのみ)
14. CV_CAP_PROP_GAIN 画像のゲイン(カメラのみ)
15. CV_CAP_PROP_EXPOSURE 露出(カメラのみ)
16. CV_CAP_PROP_CONVERT_RGB 画像をRGBに変換するかどうかを示すブールフラグ
17. CV_CAP_PROP_WHITE_BALANCE 現在サポートされていません
18. CV_CAP_PROP_RECTIFICATION ステレオカメラ用の整流フラグ(注:現在DC1394 v 2.xバックエンドでのみサポートされています)

次回の記事
Thorlabs自動ステージをPythonで動かす【研究用】