IC Imaging Control (Python)

  • サンプルプログラムトップページ
  • デバイスのオープンとハンドリング
    • デバイスを開く
    • ダイアログボックスを使用してデバイスを開く
    • デバイスプロパティ設定の保存と復元
    • プロパティの設定方法
    • 接続しているカメラ一覧を表示
    • ROIの設定方法
    • オートフォーカスで焦点を調整する範囲を指定
    • デバイスロストの検出と再接続方法
  • イメージの取得
    • 8bit静止画保存
    • 16bit静止画保存
    • Enterキーを押下したときに画像保存
    • メモリーレコーディング
    • AVIファイル保存
  • 画像処理
    • コールバック関数の設定方法(OpenCVで二値化)
    • OpenCVで画像処理して表示する方法
    • ソフトウェアトリガー・外部トリガーの使用方法
    • ステレオカメラで表示
    • 2つのカメラで取得した画像の輝度値を平均してバーに表示する
  • IC Imaging Control3.5(pythonnet編)
    • Qtを使ったデモアプリ(pythonnet編)
    • カメラで取得した画像の輝度値を平均してバーに表示する
      (pythonnet編)
    • 動画保存(MediaStreamSink コーデック:H.264)
    • 露光時間・ゲインを設定し、静止画保存をする(pythonnet編)
  • リンク集

    ICImagingControl WEB APIリファレンスマニュアル/サンプルプログラム

    :日本語対応済み :日本語化準備中
    開発言語 APIリファレンスマニュアル サンプルプログラム
    C 4.0
    ()
    - - 4.0
    ()
    - -
    C++ 4.0
    ()
    3.5
    ()
    3.4
    ()
    4.0
    ()
    3.5 3.4
    ()
    C#/VB.NET 4.0
    ()
    3.5
    ()
    3.4
    ()
    4.0
    ()
    3.5
    ()
    3.4
    ()
    Python 4.0
    ()
    3.5 3.4
    ()
    4.0
    ()
    3.5 3.4
    ()

動画保存(MediaStreamSink コーデック:H.264)

概要

IC Imaging Control 3.5のWindows専用APIを使用したPythonのプログラムでH.264のコーデックを使用して動画を保存する方法について記載しています。

サンプルプログラム

サンプル(Python) pythonnet-qt5-mediastreamsink.zip

サンプルの出力

コード全体

from PyQt5.QtGui import QPixmap, QImage         
from PyQt5.QtWidgets import QWidget,QMainWindow, QLabel, QSizePolicy, QApplication, QAction, QHBoxLayout,QMessageBox


from PyQt5.QtCore import *
import sys,traceback,os


import ctypes as C
import numpy as np
import cv2

# PyhtonNetをインポートする
import clr


# 同じフォルダ内にあるIC Imaging Control3.5のDllを参照する
clr.AddReference('TIS.Imaging.ICImagingControl35')
clr.AddReference('System')


# IC Imaging Control namespaceを宣言
import TIS.Imaging
from System import TimeSpan



class DisplayBuffer:
    '''
    このクラスは、ビデオウィンドウに表示するために画像をピックスマップにコピーするために必要です。
    '''
    locked = False
    pixmap = None

    def Copy( self, FrameBuffer):
        if(  int(FrameBuffer.FrameType.BitsPerPixel/8 ) == 4):
            imgcontent = C.cast(FrameBuffer.GetIntPtr().ToInt64(), C.POINTER(C.c_ubyte * FrameBuffer.FrameType.BufferSize))
            qimage = QImage(imgcontent.contents, FrameBuffer.FrameType.Width,FrameBuffer.FrameType.Height, QImage.Format_RGB32).mirrored()
            self.pixmap = QPixmap(qimage)

class WorkerSignals(QObject):
    display = pyqtSignal(object)


class DisplayFilter(TIS.Imaging.FrameFilterImpl):
    '''
    このフレームフィルターは、着信フレームをDisplayBufferオブジェクトにコピーし、新しいバッファーでQApplicationに信号を送ります。
    '''
    __namespace__ = "DisplayFilterClass"
    signals = WorkerSignals() 
    dispBuffer = DisplayBuffer()

    def GetSupportedInputTypes(self, frameTypes):
        frameTypes.Add( TIS.Imaging.FrameType(TIS.Imaging.MediaSubtypes.RGB32))

    def GetTransformOutputTypes(self,inType, outTypes):
        outTypes.Add(inType)
        return True

    def Transform(self, src, dest):
        dest.CopyFrom(src)
        if self.dispBuffer.locked is False:
            self.dispBuffer.locked = True
            self.dispBuffer.Copy(dest)
            self.signals.display.emit(self.dispBuffer)

        return False

####################################################################################

def SelectDevice():
    ic.LiveStop()
    ic.ShowDeviceSettingsDialog()
    if ic.DeviceValid is True:
        ic.LiveStart()
        ic.SaveDeviceStateToFile("device.xml")

def ShowProperties():
    if ic.DeviceValid is True:
        ic.ShowPropertyDialog()
        ic.SaveDeviceStateToFile("device.xml")

def Close():
    if ic.DeviceValid is True:
        ic.LiveStop()
    app.quit()

def imageCallback(x,y,buffer):
    print("hallo")
    return 0

def OnDisplay(dispBuffer):
    videowindow.setPixmap(dispBuffer.pixmap)   
    dispBuffer.locked = False   


app =  QApplication(sys.argv)

w = QMainWindow()
w.resize(640, 480)
w.move(300, 300)
w.setWindowTitle('動画保存')

# メニュー作成
mainMenu = w.menuBar()
fileMenu = mainMenu.addMenu('&ファイル')

exitAct =  QAction("&終了",app)
exitAct.setStatusTip("Exit program")
exitAct.triggered.connect(Close)
fileMenu.addAction(exitAct)

deviceMenu = mainMenu.addMenu('&デバイス')
devselAct =  QAction("&選択",app)
devselAct.triggered.connect(SelectDevice)
deviceMenu.addAction(devselAct)

devpropAct =  QAction("&プロパティ",app)
devpropAct.triggered.connect(ShowProperties)
deviceMenu.addAction(devpropAct)

layout = QHBoxLayout()
mainwindow = QWidget()
videowindow = QLabel()
layout.addWidget(videowindow)

mainwindow.setLayout(layout)
w.setCentralWidget(mainwindow)

# IC Imaging Controlオブジェクトを作成
ic = TIS.Imaging.ICImagingControl()
'''
ICは、親ウィンドウがないとライブビデオを表示できないので
フレームフィルタを使用して画像を取得し、メインスレッドに画像を表示するように指示
'''
#ic.LiveDisplay = True
# ライブ表示用に表示フィルターオブジェクトをインスタンス化
displayFilter = DisplayFilter()

# ディスプレイフィルターに接続する
displayFilter.signals.display.connect(OnDisplay)
ic.DisplayFrameFilters.Add( ic.FrameFilterCreate(displayFilter))

# MP4コンテナを取得
CurrentMediaStreamContainer = None
for container in TIS.Imaging.MediaStreamContainer.MediaStreamContainers:
    if container.Name == "MP4":
        CurrentMediaStreamContainer = container

if CurrentMediaStreamContainer is None:
    msgBox = QMessageBox(text="MP4コンテナが見つかりません。")
    msgBox.exec()
    quit()

# MediaFoundation H.264コーデックを取得
try:
    CurrentCodec = next(c for c in TIS.Imaging.AviCompressor.AviCompressors 
                        if CurrentMediaStreamContainer.IsCodecSupported(c) and 
                        c.Name == "MediaFoundation h.264")
except:
    msgBox = QMessageBox(text="MediaFoundation h.264コーデックが見つかりません。!")
    msgBox.exec()
    quit()

# 拡張性を設定
Filename = "test." + CurrentMediaStreamContainer.PreferredFileExtension
# ビデオファイルに画像データを保存するためのsinkに接続
MediaStreamSink = TIS.Imaging.MediaStreamSink(CurrentMediaStreamContainer, CurrentCodec,
                                              Filename)
ic.Sink = MediaStreamSink

#コーデックのプロパティページを表示
CurrentCodec.ShowPropertyPage()


try:
    ic.LoadDeviceStateFromFile("device.xml",True)
    if ic.DeviceValid is True:
        #録画開始
        ic.LiveStart()
except Exception as ex:
    print(ex)
    pass

w.show()

app.exec()

if ic.DeviceValid is True:
    #録画停止
    ic.LiveStop()

解説

ここでは主にH.264に保存するための方法について説明します。
displayFilterやコールバック関数の使用方法に関しては【Qtを使ったデモアプリ(pythonnet編)】を参考にしてください。

# MP4コンテナを取得
CurrentMediaStreamContainer = None
for container in TIS.Imaging.MediaStreamContainer.MediaStreamContainers:
    if container.Name == "MP4":
        CurrentMediaStreamContainer = container

if CurrentMediaStreamContainer is None:
    msgBox = QMessageBox(text="MP4コンテナが見つかりません。")
    msgBox.exec()
    quit()

MediaStreamSinkは画像データを様々なビデオフォーマットで保存することができます。またオプション次第で一つ以上のFrameFiltersを指定し、動画ファイルとして書き込む前の段階で画像データの分析や変換も可能になります。
MediaStreamSinkは高度なビデオファイルのレコーディングが可能ですが、簡単な動画撮影は【AVIファイル保存】をご覧ください。

# MediaFoundation H.264コーデックを取得
try:
    CurrentCodec = next(c for c in TIS.Imaging.AviCompressor.AviCompressors 
                        if CurrentMediaStreamContainer.IsCodecSupported(c) and 
                        c.Name == "MediaFoundation h.264")
except:
    msgBox = QMessageBox(text="MediaFoundation h.264コーデックが見つかりません。!")
    msgBox.exec()
    quit()

このコードはAviCompressor.AviCompressorsプロパティを使って利用可能なコーデックのリストを作成し、 MediaFoundation h.264があればコーデックとしてセットします。

# 拡張性を設定
Filename = "test." + CurrentMediaStreamContainer.PreferredFileExtension
# ビデオファイルに画像データを保存するためのsinkに接続
MediaStreamSink = TIS.Imaging.MediaStreamSink(CurrentMediaStreamContainer, CurrentCodec,
                                              Filename)
ic.Sink = MediaStreamSink

AVI録画を行うコーデックをためにMediaStreamSinkを作成し、IC Imaging Controlのシンク(画像の受け皿)にMediaStreamSinkを入れます。

try:
    ic.LoadDeviceStateFromFile("device.xml",True)
    if ic.DeviceValid is True:
        #録画開始
        ic.LiveStart()
except Exception as ex:
    print(ex)
    pass

w.show()

app.exec()

if ic.DeviceValid is True:
    #録画停止
    ic.LiveStop()

上記のMediaStreamSinkをIC Imaging Controlのシンクにつなぐだけで、ic.LiveStart()とic.LiveStop()を呼び出すだけで録画をすることができます。

▲ このページの先頭に戻る

Copyright © ARGO Corporation. All Rights Reserved.