pythonは海康工業カメラ画像取得方式のコールバックストリームを呼び出しopencvで表示する


シリーズ記事カタログ
第二章python言語の下で海康工業カメラを用いて、コールバック方式で画像データを取得し、表示する
 
文書ディレクトリ
目次
シリーズ記事カタログ
文書ディレクトリ
前言
一、使用前提
二、コールバックフロー(公式ルーチン説明)
1.インタフェースの説明
2.pythonでのインタフェース実装
三、コールバックしてストリームを取り、白黒画像データを解析しopencvで表示する
1.コールバックデータmono形式の画像データの取得と解析
2.画像データ表示
四、コールバックしてストリームを取り、多種の画素フォーマットの画像データを解析しopencvで表示する
1.コールバックデータ複数画素フォーマットのデータを取得し解析する
2.画像データ表示
まとめ
前言
ハイコン工業カメラの下層SDKでは、2つの異なる方式の画像データ取得方式が提供されている.1つはコールバック方式であり、1つはアクティブ取流方式である.しかし、公式例では、関連データ取得後の印刷情報のみが提供されており、画像データの解析には与えられていないが、以上の状況に基づいて、本稿では、コールバック取流方式で取得した画像データについて説明する解析.
一、使用前提
まず海康工業カメラの下層SDKをインストールする必要があり、インストール後、関連ルーチンがインストールディレクトリの下にあり、本明細書のコード呼び出しはこのディレクトリの下で呼び出す必要がある(移植して使用していない).
前章(pythonが海康工業カメラを呼び出しopencvで表示する)の海康工業カメラ接続の内容に基づいて,本稿では海康工業カメラのコールバック取図方式で取得した画像解析について説明する.
二、コールバックフロー(公式ルーチン説明)
1.インタフェースの説明
ハイコンが提供する下層SDKには、コールバックストリームに関するインタフェースがあり、インストールディレクトリの下にある工業カメラSDK開発ガイドでは、このインタフェースの具体的な紹介があり、具体的には以下の通りである.
インタフェース:MV_CC_RegisterImageCallBackEx()
C言語に対応するインタフェースは次のとおりです.
MV_CAMCTRL_API int __stdcall MV_CC_RegisterImageCallBackEx  ( void *  handle,  
                                                              void(__stdcall *cbOutput)(unsigned char *pData, MV_FRAME_OUT_INFO_EX *pstFrameInfo, void *pUser)  ,  
                                                              void *  pUser ) 

パラメータ:
.handle:デバイスハンドル
.cbOutput:コールバック関数ポインタ
.pUser:ユーザー定義変数
戻り値:
を選択します.呼び出しに成功し、MV_OKを返します.
を選択します.呼び出しに失敗し、エラーコードを返します.
注意:
1.このインタフェースにより画像データコールバック関数を設定することができ、MV_CC_CreateHandle()インタフェースの後に呼び出す必要があり、MV_CC_StarGrabbing()インタフェースの前に設定する必要がある.
2、このインタフェースはCameralinkデバイスをサポートせず、GigE、USBデバイスのみをサポートする.
2.pythonでのインタフェース実装
(1)以上の説明から分かるように、MV_CC_RegisterImageCallBackEx()インタフェースは、以下のように、オープンデバイスとオープン収集インタフェースとの間で呼び出しを宣言する必要がある.
 # ch:       | en:Register image callback
    ret = cam.MV_CC_RegisterImageCallBackEx(CALL_BACK_FUN,None)
    if ret != 0:
        print ("register image callback fail! ret[0x%x]" % ret)
        sys.exit()

(2)そして、取込インタフェースの起動と停止の間に、次のようなコードを書き込む必要がある.そうしないと、コールバック取込図は1枚の画像しか取得できない後、次のように画像の取得を停止する.
 print ("press a key to stop grabbing.")
    msvcrt.getch()

msvcrtモジュールのpython言語標準ライブラリの入力出力を制御するライブラリです.
(3)コールバック関数機能の実現
winfun_ctype = WINFUNCTYPE             #           ,          
stFrameInfo = POINTER(MV_FRAME_OUT_INFO_EX)   #    POINTER    stFrameInfo        MV_FRAME_OUT_INFO_EX
pData = POINTER(c_ubyte)       #    POINTER    pData        c_ubyte
FrameInfoCallBack = winfun_ctype(None, pData, stFrameInfo, c_void_p)   #         
#         
def image_callback(pData, pFrameInfo, pUser):
        stFrameInfo = cast(pFrameInfo, POINTER(MV_FRAME_OUT_INFO_EX)).contents
        if stFrameInfo:
            print ("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nFrameNum))
CALL_BACK_FUN = FrameInfoCallBack(image_callback)

以上の3つのステップはいずれも公式ルーチンの呼び出し紹介であり、上記のコードでは、画像データを取得した後、画像データの情報のみを印刷し、画像データを解析していないことがわかり、次に画像データを解析し、表示する.
三、コールバックしてストリームを取り、白黒画像データを解析しopencvで表示する
1.コールバックデータmono形式の画像データの取得と解析
winfun_ctype = WINFUNCTYPE
stFrameInfo = POINTER(MV_FRAME_OUT_INFO_EX)
pData = POINTER(c_ubyte)
FrameInfoCallBack = winfun_ctype(None, pData, stFrameInfo, c_void_p)
def image_callback(pData, pFrameInfo, pUser):
    global img_buff
    img_buff = None
    stFrameInfo = cast(pFrameInfo, POINTER(MV_FRAME_OUT_INFO_EX)).contents
    if stFrameInfo:
        print ("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nFrameNum))
    if img_buff is None:
        img_buff = (c_ubyte * stFrameInfo.nWidth*stFrameInfo.nHeight)()
        cdll.msvcrt.memcpy(byref(img_buff) , pData , stFrameInfo.nWidth*stFrameInfo.nHeight)
    data = np.frombuffer(img_buff , count = int(stFrameInfo.nWidth*stFrameInfo.nHeight) , dtype = np.uint8)
    image_control(data = data , stFrameInfo = stFrameInfo)
CALL_BACK_FUN = FrameInfoCallBack(image_callback)

公式ルーチンにおけるコールバック取得画像データのコード修正により、関連画像のデータが取得され、上述したコード中のdataがコールバック取得画像データであり、カスタム関数image_control()により画像データに対してreshape操作を行い、表示可能なデータが取得される.
2.画像データ表示
def image_show(image):
    image = cv2.resize(image, (600, 400), interpolation=cv2.INTER_AREA)
    cv2.imshow('fgmask', image)
    k = cv2.waitKey(1) & 0xff

def image_control(data , stFrameInfo):
    image = data.reshape((stFrameInfo.nHeight, stFrameInfo.nWidth))
    image_show(image = image)

以上のコードはコールバックで取得した画像データを表示するコードであるが、以上のコードは海康工業カメラを用いた白黒モードでのみ使用され、画素フォーマットやチャネルなどの情報は考慮されていないため、以下に多様な画素フォーマットの画像データを解析し、示す.
四、コールバックしてストリームを取り、多種の画素フォーマットの画像データを解析しopencvで表示する
1.コールバックデータ複数画素フォーマットのデータを取得し解析する
第1章(pythonが海康工業カメラを呼び出しopencvで表示する)に基づいて、常用インタフェースのパッケージについては、コールバック部分も関連内容のパッケージを行い、コールバック中のデータ解析部分を一体にパッケージし、具体的なコードは以下の通りである.
#       
winfun_ctype = WINFUNCTYPE
stFrameInfo = POINTER(MV_FRAME_OUT_INFO_EX)
pData = POINTER(c_ubyte)
FrameInfoCallBack = winfun_ctype(None, pData, stFrameInfo, c_void_p)
def image_callback(pData, pFrameInfo, pUser):
    global img_buff
    img_buff = None
    stFrameInfo = cast(pFrameInfo, POINTER(MV_FRAME_OUT_INFO_EX)).contents
    if stFrameInfo:
        print ("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (stFrameInfo.nWidth, stFrameInfo.nHeight, stFrameInfo.nFrameNum))
    if img_buff is None and stFrameInfo.enPixelType == 17301505:
        img_buff = (c_ubyte * stFrameInfo.nWidth*stFrameInfo.nHeight)()
        cdll.msvcrt.memcpy(byref(img_buff) , pData , stFrameInfo.nWidth*stFrameInfo.nHeight)
        data = np.frombuffer(img_buff , count = int(stFrameInfo.nWidth*stFrameInfo.nHeight) , dtype = np.uint8)
        image_control(data=data, stFrameInfo=stFrameInfo)
        del img_buff
    elif img_buff is None and stFrameInfo.enPixelType == 17301514:
        img_buff = (c_ubyte * stFrameInfo.nWidth*stFrameInfo.nHeight)()
        cdll.msvcrt.memcpy(byref(img_buff) , pData , stFrameInfo.nWidth*stFrameInfo.nHeight)
        data = np.frombuffer(img_buff , count = int(stFrameInfo.nWidth*stFrameInfo.nHeight) , dtype = np.uint8)
        image_control(data=data, stFrameInfo=stFrameInfo)
        del img_buff
    elif img_buff is None and stFrameInfo.enPixelType == 35127316:
        img_buff = (c_ubyte * stFrameInfo.nWidth * stFrameInfo.nHeight*3)()
        cdll.msvcrt.memcpy(byref(img_buff), pData, stFrameInfo.nWidth * stFrameInfo.nHeight*3)
        data = np.frombuffer(img_buff, count=int(stFrameInfo.nWidth * stFrameInfo.nHeight*3), dtype=np.uint8)
        image_control(data=data, stFrameInfo=stFrameInfo)
        del img_buff
    elif img_buff is None and stFrameInfo.enPixelType == 34603039:
        img_buff = (c_ubyte * stFrameInfo.nWidth * stFrameInfo.nHeight * 2)()
        cdll.msvcrt.memcpy(byref(img_buff), pData, stFrameInfo.nWidth * stFrameInfo.nHeight * 2)
        data = np.frombuffer(img_buff, count=int(stFrameInfo.nWidth * stFrameInfo.nHeight * 2), dtype=np.uint8)
        image_control(data=data, stFrameInfo=stFrameInfo)
        del img_buff
CALL_BACK_FUN = FrameInfoCallBack(image_callback)

工業カメラは常に異なる画素フォーマットがあり、異なるチャネル数に対応しているため、画像解析の過程で異なる分岐の解析方式が現れる.以上の内容は海康が提供した公式定義で取得した画素フォーマットに対応する数字に基づいて、判定を行い、具体的な定義は海康SDKディレクトリの下:../MVS/Development/Samples/Python/MvImport/PixelType_header.pyファイルで、必要に応じて自分で検索してください.
2.画像データ表示
以上から分かるように、コールバックによって取得された画像データは複数の画素フォーマットタイプであり、異なる画素フォーマットタイプの画像チャネルが異なり、自然に表示時に異なるチャネル構成のコードをもたらし、以下の内容は異なる画素フォーマットタイプの画像データの表示であり、コードは以下の通りである.
#     
def image_show(image):
    image = cv2.resize(image, (600, 400), interpolation=cv2.INTER_AREA)
    cv2.imshow('fgmask', image)
    k = cv2.waitKey(1) & 0xff

#            
def image_control(data , stFrameInfo):
    if stFrameInfo.enPixelType == 17301505:
        image = data.reshape((stFrameInfo.nHeight, stFrameInfo.nWidth))
        image_show(image=image)
    elif stFrameInfo.enPixelType == 17301514:
        data = data.reshape(stFrameInfo.nHeight, stFrameInfo.nWidth, -1)
        image = cv2.cvtColor(data, cv2.COLOR_BAYER_GB2RGB)
        image_show(image=image)
    elif stFrameInfo.enPixelType == 35127316:
        data = data.reshape(stFrameInfo.nHeight, stFrameInfo.nWidth, -1)
        image = cv2.cvtColor(data, cv2.COLOR_RGB2BGR)
        image_show(image=image)
    elif stFrameInfo.enPixelType == 34603039:
        data = data.reshape(stFrameInfo.nHeight, stFrameInfo.nWidth, -1)
        image = cv2.cvtColor(data, cv2.COLOR_YUV2BGR_Y422)
        image_show(image = image)

異なるチャネル数を見ることができ、異なるデータ変換に対応し、最終的に画像をデスクトップに表示することができます.
まとめ
工業用カメラの使用において、多くのシーンで使用されているのはコールバック方式で画像を取得することであり、コールバック方式で取得した画像データをどのように解析するかは相対的に重要であり、以上は海康工業カメラのコールバック取得画像データの解析である.C言語ベースのインタフェース変換後のpythonインタフェースを用いてカメラを呼び出す方法を選択したが,この方法は工業界で比較的よく見られる.