16bit静止画保存
概要
OpenCVのライブラリを使用して16bitのモノクロ画像(Y16)を保存します。
なお、RGB64(カラー16bit)には対応しておりませんのでご注意ください。
サンプルプログラム
サンプル(Python) | image-save-16bit-py.zip |
---|
サンプルツールの出力
コード全体
###############
# 解説1
###############
import ctypes
import tisgrabber as tis
import cv2
import numpy as np
ic = ctypes.cdll.LoadLibrary("./tisgrabber_x64.dll")
tis.declareFunctions(ic)
ic.IC_InitLibrary(0)
###############
# 解説2
###############
#新しいグラバーハンドルを作成します。
hGrabber = ic.IC_CreateGrabber()
#デバイスを選択
ic.IC_OpenDevByUniqueName(hGrabber, tis.T("DMK 33UX250 1220128"))
ic.IC_SetVideoFormat(hGrabber, tis.T("Y16 (640x480)"))
ic.IC_SetFrameRate(hGrabber, ctypes.c_float( 10.0))
###############
# 解説3
###############
#### 解説3-1
if(ic.IC_IsDevValid(hGrabber)):
# メモリ内で受け取るピクセルフォーマットを設定します。
ic.IC_SetFormat(hGrabber, tis.SinkFormats.Y16)
#ライブスタート開始 引数:0の時非表示、引数:1の時表示
ic.IC_StartLive(hGrabber, 0)
#### 解説3-2
key = ""
while key != "q":
print("p: 画像保存")
print("q: プログラム終了")
key = input('pかqを入力してください。:')
if key == "p":
#2秒間カメラから画像を送られてくるのをを待つ
if ic.IC_SnapImage(hGrabber, 2000) == tis.IC_SUCCESS:
#### 解説3-3
# 画像の解像度・フォーマットを宣言
Width = ctypes.c_long()
Height = ctypes.c_long()
BitsPerPixel = ctypes.c_int()
colorformat = ctypes.c_int()
# 画像の解像度・フォーマットを取得する
ic.IC_GetImageDescription(hGrabber, Width, Height,
BitsPerPixel, colorformat)
#### 解説3-4
# バッファサイズを計算し、ピクセルあたりのバイト数と
# numpy配列のデータ型を取得します。
elementsperpixel = 1
dtype = np.uint8
if colorformat.value == tis.SinkFormats.Y800:
elementsperpixel = 1 # 1 byte per pixel
if colorformat.value == tis.SinkFormats.Y16:
dtype = np.uint16
elementsperpixel = 1 # 1 uint16 per pixel
if colorformat.value == tis.SinkFormats.RGB24:
elementsperpixel = 3 # BGR format, 3 bytes
if colorformat.value == tis.SinkFormats.RGB32:
elementsperpixel = 4 # BGRA format, 4 bytes
#### 解説3-5
buffer_size = Width.value * Height.value * int(float(BitsPerPixel.value) / 8.0)
# イメージデータ取得
imagePtr = ic.IC_GetImagePtr(hGrabber)
imagedata = ctypes.cast(imagePtr,
ctypes.POINTER(ctypes.c_ubyte *
buffer_size))
#### 解説3-6
# numpy配列取得
image = np.ndarray(buffer=imagedata.contents,
dtype=dtype,
shape=(Height.value,
Width.value,
elementsperpixel))
#### 解説3-7
# OpenCVの関数
image = cv2.flip(image, 0) #画像反転
cv2.imwrite("image.png",image)
print("画像を保存しました。")
cv2.waitKey(10)
else:
print("2秒間フレームを受け取っていません。")
ic.IC_StopLive(hGrabber)
else:
ic.IC_MsgBox(tis.T("デバイスを開けませんでした。"), tis.T("Simple Live Video"))
ic.IC_ReleaseGrabber(hGrabber)
使用するファイルについて
【callback_python.py】を動かす為に必ず下記の【dll(ライブラリ)】や【tisgrabber.py】が必要となります。dll(Dynamic Link Library、ダイナミックリンクライブラリ)とは、Windowsにおける共有ライブラリのことで、メーカーがユーザレベルで操作できるように管理しています。これらのdllを【tisgrabber.py】経由で読み込むことで、TheImagingSource社のカメラに簡単にアクセスできます。
tisgrabber.py | TheImagingSource社が提供するAPIであるIC Imaging Controlをカプセル化するtisgrabber.dllのラッパープログラム(IC Imaging Controlを使いやすくするためのもの)となっています。IC Imaging Control DLLの32ビットバージョン(tisgrabber.dll、TIS_UDSHL11.dll)と64ビットバージョン(tisgrabber_x64.dll、TIS_UDSHL11_64.dll)のどちらを使用するかが自動的にチェックしたり、IC Imaging Controlで使用されているメソッドを呼び出すために使われています。 |
---|---|
tisgrabber.dll | IC Imaging ControlをPythonで呼び出すための32 bitバージョンのDLL |
TIS_UDSHL11.dll | IC Imaging Controlの32 bitバージョンのDLL |
tisgrabber_x64.dll | IC Imaging ControlをPythonで呼び出すための64 bitバージョンのDLL |
TIS_UDSHL11_64.dll | IC Imaging Controlの64 bitバージョンのDLL |
callback_python.py (任意のプログラム) |
実行されるメインプログラム。 |
解説1:importで宣言する
import ctypes
import tisgrabber as tis
import cv2
import numpy as np
ic = ctypes.cdll.LoadLibrary("./tisgrabber_x64.dll")
tis.declareFunctions(ic)
ic.IC_InitLibrary(0)
Pythonで下記のライブラリを使用するためにimportを使います。
ctype | このライブラリは C と互換性のあるデータ型を提供し、共有ライブラリ(Windowsでは*.dll)の関数を呼び出すことができます。 |
---|---|
tisgrabber | IC Imaging Controlを制御するラッパーファイルを読み込むために使用します。 |
cv2 | OpenCVで画像処理を行うために使用します。 |
numpy | Pythonでの機械学習の計算をより速く、効率的に行えるようにするために使用します。 |
上記のライブラリを使用するため、あらかじめターミナルにて下記のコマンドを入力し、各ライブラリをインストールしておいてください。
pip install opencv-python
pip install numpy
解説2:カメラをオープンする
#########
# 解説2
#########
#新しいグラバーハンドルを作成
hGrabber = ic.IC_CreateGrabber()
#デバイスを選択
ic.IC_OpenDevByUniqueName(hGrabber, tis.T("DMK 33UX250 1220128"))
#640x480のモノクロ16bitに設定
ic.IC_SetVideoFormat(hGrabber, tis.T("Y16 (640x480)"))
#フレームレートを10fpsに設定
ic.IC_SetFrameRate(hGrabber, ctypes.c_float( 10.0))
カメラを開くためにまず「ic.IC_CreateGrabber」でオブジェクトを作成し、「IC_OpenDevByUniqueName」でデバイスの型番と8桁のシリアル番号からカメラを開きます。デバイスモデルと8桁シリアル番号をスペースでサンプルのように区切って作成してください。なお、シリアル番号の頭文字がゼロの場合、先頭のゼロは省略されますので注意してください。 その後、「IC_SetVideoFormat」で解像度、「IC_SetFrameRate」でフレームレートを設定します。
ここでは、カメラの型番、シリアル番号、解像度、フレームレートが既知の状態でプログラム上で決め打ちしていますが、下記の関数によってデバイスダイアログを呼んでカメラを指定することもできます。
hGrabber = tis.openDevice(ic)
設定方法に関しては下記を参照ください。
解説3:ライブスタート開始し、画像を保存する
###############
# 解説3
###############
#### 解説3-1
if(ic.IC_IsDevValid(hGrabber)):
# メモリ内で受け取るピクセルフォーマットを設定します。
ic.IC_SetFormat(hGrabber, tis.SinkFormats.Y16)
#ライブスタート開始 引数:0の時非表示、引数:1の時表示
ic.IC_StartLive(hGrabber, 0)
#### 解説3-2
key = ""
while key != "q":
print("p: 画像保存")
print("q: プログラム終了")
key = input('pかqを入力してください。:')
if key == "p":
#2秒間カメラから画像を送られてくるのをを待つ
if ic.IC_SnapImage(hGrabber, 2000) == tis.IC_SUCCESS:
#### 解説3-3
# 画像の解像度・フォーマットを宣言
Width = ctypes.c_long()
Height = ctypes.c_long()
BitsPerPixel = ctypes.c_int()
colorformat = ctypes.c_int()
# 画像の解像度・フォーマットを取得する
ic.IC_GetImageDescription(hGrabber, Width, Height,
BitsPerPixel, colorformat)
#### 解説3-4
# バッファサイズを計算し、ピクセルあたりのバイト数と
# numpy配列のデータ型を取得します。
elementsperpixel = 1
dtype = np.uint8
if colorformat.value == tis.SinkFormats.Y800:
elementsperpixel = 1 # 1 byte per pixel
if colorformat.value == tis.SinkFormats.Y16:
dtype = np.uint16
elementsperpixel = 1 # 1 uint16 per pixel
if colorformat.value == tis.SinkFormats.RGB24:
elementsperpixel = 3 # BGR format, 3 bytes
if colorformat.value == tis.SinkFormats.RGB32:
elementsperpixel = 4 # BGRA format, 4 bytes
#### 解説3-5
buffer_size = Width.value * Height.value * int(float(BitsPerPixel.value) / 8.0)
# イメージデータ取得
imagePtr = ic.IC_GetImagePtr(hGrabber)
imagedata = ctypes.cast(imagePtr,
ctypes.POINTER(ctypes.c_ubyte *
buffer_size))
#### 解説3-6
# numpy配列取得
image = np.ndarray(buffer=imagedata.contents,
dtype=dtype,
shape=(Height.value,
Width.value,
elementsperpixel))
#### 解説3-7
# OpenCVの関数
image = cv2.flip(image, 0) #画像反転
cv2.imwrite("image.png",image)
print("画像を保存しました。")
cv2.waitKey(10)
else:
print("2秒間フレームを受け取っていません。")
ic.IC_StopLive(hGrabber)
else:
ic.IC_MsgBox(tis.T("デバイスを開けませんでした。"), tis.T("Simple Live Video"))
ic.IC_ReleaseGrabber(hGrabber)
TISカメラから送られてくる画像を2秒間待ち、取得したら画像を保存しています。
主な手順は下記の通りです。
解説3-1:カメラのライブスタート開始
if(ic.IC_IsDevValid(hGrabber)):
# メモリ内で受け取るピクセルフォーマットを設定します。
ic.IC_SetFormat(hGrabber, tis.SinkFormats.Y16)
#ライブスタート開始 引数:0の時非表示、引数:1の時表示
ic.IC_StartLive(hGrabber, 0)
解説2で「ic.IC_SetVideoFormat(hGrabber, tis.T("Y16 (640x480)"))」を設定していますので、メモリ内で受け取るピクセルフォーマットも同じカラーフォーマット"Y16"(モノクロ16bit)に設定します。「IC_SetVideoFormat」で設定したカラーフォーマットと「IC_SetFormat」は同じ必要があります。
「IC_StartLive」でライブストリーミングを開始しカメラから画像を送られてきます。
解説3-2:カメラから送られた画像を取得
key = ""
while key != "q":
print("p: 画像保存")
print("q: プログラム終了")
key = input('pかqを入力してください。:')
if key == "p":
#2秒間カメラから画像を送られてくるのをを待つ
if ic.IC_SnapImage(hGrabber, 2000) == tis.IC_SUCCESS:
任意のタイミングで保存処理できるようにするために、ターミナルにて【画像保存】するのか、【プログラム終了】するのか選択できるようにします。
【画像保存】する場合、「IC_SnapImage(hGrabber, 2000)」で2000ms(2秒間)カメラから画像を送られてくるのを待ちます。画像が送られてこなかったらエラーを返します。なお、IC_SnapImageの第2引数はカメラからの応答を待つタイムアウトの時間ですので、値を小さくしても処理が早くなることはありません。任意のタイミングではなく、カメラから送られてくるすべての画像を取得するのであれば、下記のコールバック関数を使った処理の方が向いています。
コールバック関数の設定方法(OpenCVで二値化)
IC Imaging Control(Python) サンプルプログラム
解説3-3:カメラから送られた画像を取得
# 画像の解像度・フォーマットを宣言
Width = ctypes.c_long()
Height = ctypes.c_long()
BitsPerPixel = ctypes.c_int()
colorformat = ctypes.c_int()
# 画像の解像度・フォーマットを取得する
ic.IC_GetImageDescription(hGrabber, Width, Height,
BitsPerPixel, colorformat)
カメラからデータを受け取り、IC_GetImageDescription関数で受け取った画像の横幅、高さ、1ピクセル当たりのデータ量、カラーフォーマットを取得します。
解説3-4:バッファサイズを計算
# バッファサイズを計算し、ピクセルあたりのバイト数と
# numpy配列のデータ型を取得します。
elementsperpixel = 1
dtype = np.uint8
if colorformat.value == tis.SinkFormats.Y800:
elementsperpixel = 1 # 1 byte per pixel
if colorformat.value == tis.SinkFormats.Y16:
dtype = np.uint16
elementsperpixel = 1 # 1 uint16 per pixel
if colorformat.value == tis.SinkFormats.RGB24:
elementsperpixel = 3 # BGR format, 3 bytes
if colorformat.value == tis.SinkFormats.RGB32:
elementsperpixel = 4 # BGRA format, 4 bytes
データ量をカラーフォーマットによって変換しています。データ量はそれぞれ下記の通りです。
Y800 | モノクロ8bit(1Byte) |
---|---|
Y16 | モノクロ16bit(2Byteだが16 ビット符号なし(uint16)として処理するため、uint16の1Byteとして処理) |
RGB24 | カラー8bit(3Byte RGBそれぞれ8bit) |
RGB32 | カラー8bit(4Byte RGBAそれぞれ8bit)アルファ値(透過度)はIC Imaging Controlでは使っていないため常に"0"です。 |
なお、RGB64はIC Imaging Control3.4ではサポートしていませんが、IC Imaging Control3.5ではサポートしており、Tiff形式で保存することも可能です。
露光時間・ゲインを設定し、静止画保存をする(pythonnet編)
IC Imaging Control(Python) サンプルプログラム
解説3-5:イメージデータを取得
buffer_size = Width.value * Height.value * int(float(BitsPerPixel.value) / 8.0)
# イメージデータ取得
imagePtr = ic.IC_GetImagePtr(hGrabber)
imagedata = ctypes.cast(imagePtr,
ctypes.POINTER(ctypes.c_ubyte *
buffer_size))
IC_GetImagePtrでbit形式のイメージデータのポインタimagePtrを取得しています。imagePtrのポインタ型を使って、画像データの先頭から画像の最後のアドレスを指定し、ポインタ型に変換(ctypes.cast) しています。ポインタ変数imagedata が格納している画像データが入っているアドレスそのものですので、imagedataには画像データが格納されていることになります。
解説3-6:NumPy配列化する
# numpy配列取得
image = np.ndarray(buffer=imagedata.contents,
dtype=dtype,
shape=(Height.value,
Width.value,
elementsperpixel))
上記によって取得したimagedataを使ってNumpy配列を生成します。OpenCVで読み込む画像イメージがNumPyの配列であるndarray形式で表現されるため、上記のように変換する必要があります。
解説3-7:リアルタイムでOpenCVの画像処理し16bitで保存する
# OpenCVの関数
image = cv2.flip(image, 0) #画像反転
cv2.imwrite("image.png",image)
print("画像を保存しました。")
cv2.waitKey(10)
else:
print("2秒間フレームを受け取っていません。")
ic.IC_StopLive(hGrabber)
else:
ic.IC_MsgBox(tis.T("デバイスを開けませんでした。"), tis.T("Simple Live Video"))
ic.IC_ReleaseGrabber(hGrabber)
NumPyの配列で取得した画像をOpenCVの画像反転メソッドflipを使って反転させてからimwriteで16bit形式のモノクロ画像を保存しています。
【プログラム終了】する場合、「ic.IC_StopLive(hGrabber)」が実行され、「ic.IC_ReleaseGrabber(hGrabber)」でhGrabberオブジェクトが解放され処理が終了します。