« wxpythonとvtkでビデオプレーヤー作ってみる。その3。vtkImageViewerでjpeg表示。 | トップページ | wxpythonとvtkでビデオプレーヤー作ってみる。その5。完成。opencvとvtkImageViewerで読み込み・表示。 »

2013年6月21日 (金)

wxpythonとvtkでビデオプレーヤー作ってみる。その4。vtkImageViewerでnumpyアレイ表示。

目次

前置き

vtk使い始めなので、とりあえずなんか作ってみるという意味でビデオプレーヤーを作っていく企画の第3弾です。

画像をアップデートする

Numpy_buffer_update_btn_2

前回までにvtkImageViewerを使って画像を表示出来るようになったので、今度は画像ファイルの代わりにnumpyで作ったランダムノイズを表示して、さらにはボタンを押したら画像がアップデートされるようにしたいと思います。そこまで行けばビデオプレーヤーはできたも同然ですし、色々なアプリのひな形にするには単純な方がいいので、無駄を省いたビデオプレーヤーの一歩手前をつくります。

numpyのランダムノイズをdataImporterに渡すのはその2で既にやったので特に説明は要りませんね。あとはimageViewer.SetInputConnectionにdataImporter.GetOutputPort()を渡すだけです。

イベント処理

問題なのはアップデートするためのイベントを拾ってimageViewerに新しい画像のバッファーを渡すところです。site-packages\vtk\wxにあるwxVTKRenderWindow.pyのコードをみると、

----------------------------------------
Methods to override (all take a wx.Event):

OnButtonDown(event)  default: propagate event to Left, Right, Middle
OnLeftDown(event)    default: set _Mode to 'Rotate'
OnRightDown(event)   default: set _Mode to 'Zoom'
OnMiddleDown(event)  default: set _Mode to 'Pan'

OnButtonUp(event)    default: propagate event to L, R, M and unset _Mode
OnLeftUp(event)
OnRightUp(event)
OnMiddleUp(event)

OnMotion(event)      default: call appropriate handler for _Mode

OnEnterWindow(event) default: set focus to this window
OnLeaveWindow(event) default: release focus

OnKeyDown(event)     default: [R]eset, [W]irefreme, [S]olid, [P]ick
OnKeyUp(event)
OnChar(event)

OnSetFocus(event)
OnKillFocus(event)

OnSize(event)
OnMove(event)

OnPaint(event)       default: Render()

----------------------------------------

のようにあるので、wxVTKRenderWindowの方でいろいろとイベントを持って行ってしまうようです。その場合、wxVTKRenderWindowをサブクラスして使いたいイベントのメソッドをオーバーロードしないといけない感じでした。

かといっても、vtkにイベントが行くかどうかは、なぜかつかっているアクターによるようです(未確認)。いままでの例だとvtk.vtkActor()を使ってましたが、これだとマウスクリックとか、キーボードイベントとかいろいろと持って行かれてしまうみたいです。

ところが、vtk.vtkImageViewer()の場合、wxのイベントを普通にwxのイベント処理で拾えました。vtkImageViewerの場合内部でvtk.vtkActor()じゃなくActor2Dというのを使っているからかもしれません。

今回のコード

(追記。今回のコードでは画像のアップデートのところでnumpy アレイのコピーが起こっていて、いまいち遅いです。次の記事ではコピーなしでやっていますので参照ください。)

そんなわけで、今回のサンプルです。アップデートボタンを押すとバッファーが更新されてランダムノイズが変化します。ここまで来ればできたも同然。

import numpy as np
import vtk
from vtk.wx.wxVTKRenderWindow import wxVTKRenderWindow
import wx


class Test(wx.Frame):

    def __init__ (self):

        wx.Frame.__init__(self, None, title='Update_vtkImageViewer_numpy')
        canvas = wx.Panel(self, size=(w,h))
        rwi = wxVTKRenderWindow(canvas, -1)
        rwi.Enable(True)
        self.setupRender() # setting up self.renderer here
        rwi.GetRenderWindow().AddRenderer(self.renderer)

        btn = wx.Button(self, -1, 'Update')
        btn.Bind(wx.EVT_BUTTON, self.updateimg)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(canvas, 1, wx.EXPAND)
        sizer.Add(btn, 0, wx.EXPAND)
        self.SetSizerAndFit(sizer)
        self.Layout()
        self.Show()

    def updateimg(self, event):

        data_matrix = np.random.randint(0,255,(h,w)).astype(np.uint8)
        self.dataImporter.CopyImportVoidPointer(data_matrix, data_matrix.nbytes)
        self.imageViewer.SetInputConnection( self.dataImporter.GetOutputPort() )
        self.Refresh()

    def setupRender(self):

        # Set a numpy array up and import it to vtk
        data_matrix = np.random.randint(0,255,(h,w)).astype(np.uint8)
        dataImporter = vtk.vtkImageImport()
        dataImporter.CopyImportVoidPointer(data_matrix, data_matrix.nbytes)
        dataImporter.SetDataScalarTypeToUnsignedChar()
        dataImporter.SetNumberOfScalarComponents(1)
        dataImporter.SetDataExtent(0, w-1, 0, h-1, 0, 0)
        dataImporter.SetWholeExtent(0, w-1, 0, h-1, 0, 0)

        imageViewer = vtk.vtkImageViewer()
        imageViewer.SetInputConnection( dataImporter.GetOutputPort() )
        imageViewer.SetColorWindow( 255 );
        imageViewer.SetColorLevel ( 128 );

        renderer = vtk.vtkRenderer()
        renderer.AddActor(imageViewer.GetActor2D())

        self.renderer = renderer
        self.imageViewer = imageViewer
        self.dataImporter = dataImporter


if __name__ == '__main__':
    app = wx.App(0)
    w,h = 64*5, 48*5
    frame = Test()
    app.MainLoop()

« wxpythonとvtkでビデオプレーヤー作ってみる。その3。vtkImageViewerでjpeg表示。 | トップページ | wxpythonとvtkでビデオプレーヤー作ってみる。その5。完成。opencvとvtkImageViewerで読み込み・表示。 »

Python」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

« wxpythonとvtkでビデオプレーヤー作ってみる。その3。vtkImageViewerでjpeg表示。 | トップページ | wxpythonとvtkでビデオプレーヤー作ってみる。その5。完成。opencvとvtkImageViewerで読み込み・表示。 »

しろののツイッタータイムライン

  • ツイッターは5つ目も凍結されました。6つ目での復活も不可能。なのでnoteに注力しています。

    と思ったら、イーロン・マスクの買収が公になってアカウントが復活できました。ありがとうマスク。

    トランプ関連記事の一覧リスト

オススメたち

2024年12月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

はてブ

無料ブログはココログ