産業用UVCカメラのすすめ 産業用UVCカメラのすすめ

※画面を横にするとパソコン版のレイアウトでご覧いただけます。正しく表示されていない場合は横向きでご覧ください。

トリガー入力されたタイミングで静止画保存

概要

この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キーを押してプログラムを停止します。