トリガー入力されたタイミングで静止画保存
概要
このPythonのサンプルでは、カメラをトリガーモードに設定し、カメラに対してトリガー入力したタイミングで静止画を1枚出力します。取得された静止画は収縮処理をして表示と保存がなされます。
開発環境
対象OS | Ubuntu 18.04.4 LTS |
---|---|
開発言語 | Python3.6.9 |
必要なパッケージ | python-opencv, python-gst-1.0, tiscamera1.0.0 |
サンプルプログラムダウンロード
モバイルサイトではご利用いただけません。
実行結果
コード全体
from re import T
import sys
#sys.path.append("../python-common")
import cv2 as cv2
import numpy as np
import os
import TIS
import time
from collections import namedtuple
class CustomData:
def __init__(self, ):
self.imagecounter = 0
self.busy = False
def on_new_image(tis, userdata):
# ビジー状態のときは回避
if userdata.busy is True:
return
userdata.busy = True
image = tis.Get_image()
# 画像処理を記載
# 例:収縮処理
kernel = np.ones((5, 5), np.uint8)
image = cv2.erode(image, kernel, iterations=5)
# 保存するJpegファイルにインデックスナンバーを付与
userdata.imagecounter += 1;
filename = "./image{:04}.jpg".format(userdata.imagecounter)
# jpegで保存
cv2.imwrite(filename, image)
userdata.busy = False
Tis = TIS.TIS()
#Tis.openDevice("29910443", 640, 480, "30/1", TIS.SinkFormats.GRAY8,True)
if not Tis.selectDevice():
quit(0)
# CustomData classをインスタンス化
CD = CustomData()
#Gstreamerのパイプラインを実行している間は画像処理を避けるためにビジーをTrueにする
CD.busy = True
# コールバック関数を定義
Tis.Set_Image_Callback(on_new_image, CD)
# トリガーモードをOFF
Tis.Set_Property("TriggerMode", "Off")
# ホワイトバランスを定義(モノクロカメラの場合スルー)
try:
Tis.Set_Property("BalanceWhiteAuto", "Off")
Tis.Set_Property("BalanceWhiteRed", 1.2)
Tis.Set_Property("BalanceWhiteGreen", 1.0)
Tis.Set_Property("BalanceWhiteBlue", 1.4)
except Exception as error:
print(error)
# ゲインと露光時間の自動をOFFにする
try:
# Disable gain and exposure automatic
Tis.Set_Property("GainAuto", "Off")
Tis.Set_Property("Gain",0)
Tis.Set_Property("ExposureAuto", "Off")
Tis.Set_Property("ExposureTime", 24000)
except Exception as error:
print(error)
Tis.Start_pipeline()
#トリガーモードOn
Tis.Set_Property("TriggerMode", "On")
#トリガーモードをカメラに適用する待ち時間
time.sleep(0.1)
#ソフトウェアトリガーをONにする
# ループ処理
while True:
key = input("q : quit\nPlease enter:")
Tis.execute_command("TriggerSoftware")
if key == "q":
break
Tis.Stop_pipeline()
print('Program end')
使用するファイルについて
TIS.py
GStreamerコードとプロパティ処理のラッパーとして、tiscameraリポジトリの GStreamerモジュールを使用しています。このプログラムファイルには、GStreamerコードのラッパーである「TIS」クラスが実装されていますので、TISクラスを使用することでGStreamerのパイプラインを記載することなく、コーディングすることが可能です。
ExternalTriggerProgram.py
メインファイル
なお、本プログラムを実行する前にメーカー製のSDK(tiscamera)をインストールを行ったうえでサンプルプログラムExternalTriggerProgram.pyを実行してください。インストール方法は下記のユーザーズガイドを参照してください。
https://www.argocorp.com/software/DL/tis/Linux/index.html#usersguide
importで宣言する
import sys
import cv2
import numpy as np
import time
from collections import namedtuple
#python_commonフォルダ内にあるファイルを確認
#python_commonフォルダ内にTIS.pyファイルがないと動作しません。
sys.path.append("/python_common")
from python_common import TIS
Pythonで下記のライブラリを使用するためにimportを使います。
sys | Pythonの実行環境に関する情報を扱うためのライブラリです(下記では未使用)。 |
---|---|
cv2 | OpenCVで画像処理を行うために使用します。 |
numpy | Pythonでの機械学習の計算をより速く、効率的に行えるようにするために使用します。 |
time | スリープ時間を使うために使用します。 |
TIS | python_commonフォルダ内にあるIC Imaging Controlを制御するラッパーファイルTIS.pyを読み込むために使用します。 |
コールバック関数定義
class CustomData:
def __init__(self, ):
self.imagecounter = 0;
self.busy = False;
def on_new_image(tis, userdata):
# ビジー状態のときは回避
if userdata.busy is True:
return
userdata.busy = True
image = tis.Get_image()
# 画像処理を記載
# 例:収縮処理
kernel = np.ones((5, 5), np.uint8)
image = cv2.erode(image, kernel, iterations=5)
# 保存するJpegファイルにインデックスナンバーを付与
userdata.imagecounter += 1;
filename = "./image{:04}.jpg".format(userdata.imagecounter)
# jpegで保存
cv2.imwrite(filename, image)
userdata.busy = False
新しい画像のコールバック関数に渡されるユーザーデータのサンプルクラスCustomDataを定義しています。
CustomDataクラス内のプロパティとして、Boolean型のbusy とinteger型のimagecounter をコールバック関数on_new_imageで使用するために定義しています。busy フラグがTrueの場合、コールバックは呼び出されませんが、Falseの場合、コールバックコールは有効となっています。これはコールバック関数が実行中に、再度コールバック関数を呼び出されても無効化にするのとコールバック関数のタイミングをbusy フラグで制御するためです。また、コールバック関数が何回呼び出されたのかをカウントするためにimagecounterを使用します。
コールバック関数on_new_imageでは、tis.Get_image()で画像を取得し、取得した画像をOpenCVのerode処理によって画像処理しています。erode処理は収縮処理と呼ばれ、2値化した画像の白い部分を収縮させています。これによって画像上の白いノイズの除去することができます。その後、erode処理によって画像処理された画像をimwrite(filename, image)でjpgファイルとして保存しています。ファイル名の最後にはコールバック関数が呼ばれた回数imagecounter が付きます。例えば、12回目に実行されたコールバック関数には「image12.jpg」が保存されます。
デバイスのオープン
Tis = TIS.TIS()
Tis.openDevice("16710581", 640, 480, "1/1", TIS.SinkFormats.GRAY8,True)
#if not Tis.selectDevice():
# quit(0)
Tis.openDevice()で明示的にデバイスをオープンすることができます。その際、引数にTis.openDevice("シリアル番号", 横解像度, 縦解像度, "フレームレート", カラーフォーマット,画面表示)を割り当てることで、カメラをオープンすることができます。また、Tis.selectDevice()でデバイス設定画面から設定する事もできます。
busyモードをONにして設定
CD = CustomData()
#Gstreamerのパイプラインを実行している間は画像処理を避けるためにビジーをTrueにする
CD.busy = True
busyモードをONにしてコールバックが走らない状態にして、プロパティ設定をできるようにします。
トリガーモードをリセット
# USBカメラの引数
Tis.Set_Property("Trigger Mode", False)
#GigEカメラの引数
#Tis.Set_Property("Trigger Mode", "Off")
# コールバック関数を呼び出す
Tis.Set_Image_Callback(on_new_image, CD)
# パイプラインをスタートする
Tis.Start_pipeline()
プロパティ設定前にトリガーモードをリセットし、コールバック関数が使用できる状態に設定します。その後パイプラインをONにすることで、カメラからフレームを取得する度にコールバック関数が呼ばれるようになります。
デバイスプロパティの設定
# ホワイトバランスを定義(モノクロカメラの場合、以下例外処理となります)
try:
Tis.Set_Property("BalanceWhiteAuto", "Off")
Tis.Set_Property("BalanceWhiteRed", 1.2)
Tis.Set_Property("BalanceWhiteGreen", 1.0)
Tis.Set_Property("BalanceWhiteBlue", 1.4)
except Exception as error:
print(error)
# ゲインと露光時間の自動をOFFにする
try:
Tis.Set_Property("GainAuto", "Off")
Tis.Set_Property("Gain",0)
Tis.Set_Property("ExposureAuto", "Off")
Tis.Set_Property("ExposureTime", 24000)
except Exception as error:
print(error)
ホワイトバランスとゲインと露光時間のプロパティ設定します。Tis.List_Properties()で設定可能プロパティ一覧を表示できます。
トリガーモードの設定
# トリガーモードOn
Tis.Set_Property("TriggerMode", "On")
#トリガーモードをカメラに適用する待ち時間
time.sleep(0.1)
プロパティ設定でトリガーモードを設定します。トリガーモードになる前にカメラから送られたフレームをコールバック関数の処理が終わるのを待つために0.1秒間スリープ状態にします。
busyモードをOFFにしてプロパティ設定を完了する
#ビジーモードをOFFにして処理を開始
CD.busy = False
busyモードをOFFにする事でコールバック関数が走る状態にします。トリガーの入力を待ちます。
ソフトウェアトリガー・プログラム動作の停止
変更後:
# ループ処理
while True:
key = input("q : quit\nPlease enter:")
Tis.execute_command("TriggerSoftware") #ソフトウェアトリガー ハードウェアトリガーの場合はコメントアウトしてください
if key == "q":
break
上記のプロパティ設定をすることでソフトウェアトリガーを発光することができます。ハードトリガー(外部トリガー)を利用する場合は、このタイミングでカメラの背面コネクタ部分に外部トリガー信号を入力します。
qキーを押してプログラムを停止します。