Skip to content

scikit-image 解析 & 輪郭抽出(GbE-2 / Python)

This content is not available in your language yet.

HelloWorld で作成した共通モジュール puclib.py を使用して、GbE-2 から取得した画像に対して scikit-image (skimage) と matplotlib で科学技術計算レベルの画像解析(大津の二値化・輪郭抽出)を行い、結果をグラフ化して保存するプログラムの作成手順です。

  1. スクリプトの作成

    puclib.py と同じフォルダーに gbe2_skimage_single_process.py を作成し、以下のコードを記述します。

    gbe2_skimage_single_process.py
    from ctypes import c_uint32, c_ushort, c_ubyte, c_void_p, byref
    import numpy as np
    import matplotlib.pyplot as plt
    from skimage import filters, measure
    # 共通モジュール puclib.py から読み込み
    from puclib import (
    load_sdk, PUC_SUCCEEDED, PUC_DETECT_TARGET_HAWK,
    PUC_Q_COUNT, PUC_DETECT_FILTER, PUC_DETECT_INFO, PUC_XFER_DATA_INFO
    )
    def main():
    print("INFINICAM GbE-2 scikit-image 解析サンプル開始...")
    # 1. SDKのロードと初期化
    puclib = load_sdk()
    if puclib.PUC_Initialize() != PUC_SUCCEEDED:
    print("エラー: SDKの初期化に失敗しました。")
    return
    # 2. デバイスの検索とオープン
    detect_filter = PUC_DETECT_FILTER(nDeviceTypeFlags=PUC_DETECT_TARGET_HAWK)
    detect_info = PUC_DETECT_INFO()
    if puclib.PUC_DetectDevice2(byref(detect_filter), byref(detect_info)) != PUC_SUCCEEDED or detect_info.nDeviceCount == 0:
    print("エラー: GbE-2 カメラが見つかりませんでした。")
    return
    h_device = c_void_p()
    if puclib.PUC_OpenDevice2(0, byref(h_device)) != PUC_SUCCEEDED:
    print("エラー: デバイスのオープンに失敗しました。")
    return
    # 3. 解像度・量子化テーブル・転送サイズの取得
    width, height = c_uint32(), c_uint32()
    puclib.PUC_GetResolution(h_device, byref(width), byref(height))
    w, h = width.value, height.value
    q_vals = (c_ushort * PUC_Q_COUNT)()
    puclib.PUC_GetQuantization2(h_device, q_vals)
    xfer_data_size = c_uint32()
    puclib.PUC_GetXferDataSize(h_device, byref(xfer_data_size))
    print(f"解像度: {w} x {h} ピクセル")
    # 4. バッファの確保
    comp_buffer = (c_ubyte * xfer_data_size.value)()
    line_bytes = (w + 3) & ~3 # 4バイト境界アラインメント
    decoded_buffer = (c_ubyte * (line_bytes * h))()
    # 5. 1フレームキャプチャの実行
    xfer_info = PUC_XFER_DATA_INFO()
    xfer_info.pData = comp_buffer
    xfer_info.nDataSize = xfer_data_size.value
    print("1フレーム撮影中...")
    if puclib.PUC_GetSingleXferData(h_device, byref(xfer_info)) == PUC_SUCCEEDED:
    # 6. 復号処理
    ret = puclib.PUC_DecodeData(
    decoded_buffer, 0, 0, w, h, line_bytes, comp_buffer, q_vals
    )
    if ret == PUC_SUCCEEDED:
    # 7. NumPy 配列へ変換
    img = np.ctypeslib.as_array(decoded_buffer).reshape((h, line_bytes))[:, :w]
    # 8. scikit-image による解析処理
    # 大津の二値化アルゴリズムでクラス間分散を最大化する自動閾値を決定
    thresh = filters.threshold_otsu(img)
    binary_img = img > thresh
    # 二値化画像に対してマーチングキューブ法に基づく輪郭(コンター)検出
    contours = measure.find_contours(binary_img, 0.5)
    # 9. Matplotlib で解析画像の描画・プロット
    fig, ax = plt.subplots(1, 2, figsize=(10, 5))
    # 左: 元画像
    ax[0].imshow(img, cmap='gray')
    ax[0].set_title('Original Image')
    ax[0].axis('off')
    # 右: 二値化画像 + 抽出した輪郭線(赤色)の重ね描き
    ax[1].imshow(binary_img, cmap='gray')
    for contour in contours:
    ax[1].plot(contour[:, 1], contour[:, 0], linewidth=1.5, color='red')
    ax[1].set_title(f'Otsu Thresholding & Contours (Threshold: {thresh:.1f})')
    ax[1].axis('off')
    plt.tight_layout()
    # 保存
    filename = "skimage_analysis_result.png"
    plt.savefig(filename, bbox_inches='tight', dpi=150)
    print(f"SUCCESS: 解析結果プロットを保存しました ({filename})")
    # 表示
    plt.show()
    else:
    print(f"エラー: 画像データの復号に失敗しました。ErrorCode: {ret}")
    else:
    print("エラー: 画像データの取得に失敗しました。")
    # 10. クローズ
    puclib.PUC_CloseDevice(h_device)
    if __name__ == "__main__":
    main()
  2. スクリプトの実行

    Terminal window
    python gbe2_skimage_single_process.py

    実行すると Matplotlib のグラフ表示画面が立ち上がり、左側に原画像、右側に大津の閾値で分割された二値化画像と検出された輪郭線(赤)が表示されます。ウィンドウを閉じるとカレントディレクトリに skimage_analysis_result.png が保存されます。


1. 自動二値化(filters.threshold_otsu)

Section titled “1. 自動二値化(filters.threshold_otsu)”

画像のヒストグラムから、前景色(被写体)と背景色を最も綺麗に切り分ける単一の閾値を統計的に決定します。明るさが固定でない環境での自動物体領域抽出に非常に強力です。

2. 高精度な輪郭抽出(measure.find_contours)

Section titled “2. 高精度な輪郭抽出(measure.find_contours)”

ピクセル単位ではなく、境界の連続性を補間計算しながら正確な 2 次元座標リストとして輪郭線を取得します。物体の面積や周囲長、円形度の計測など、計装・形状解析の前処理に役立ちます。