« wxpythonとvtkでビデオプレーヤー作ってみる。その1。C++のJpeg表示サンプルをPythonに翻訳。 | トップページ | wxpythonとvtkでビデオプレーヤー作ってみる。その3。vtkImageViewerでjpeg表示。 »

2013年6月19日 (水)

wxpythonとvtkでビデオプレーヤー作ってみる。その2。numpyアレイで用意した2Dテクスチャを四角ポリゴンに貼る。

目次

前置き

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

numpyアレイをテクスチャーとして表示する

(追記。vtkImageCanvasSource2Dというクラスが用意されているので、この辺のサンプルを参考して、このクラスを使ってやったほうがいいかと思われます。更にvtkImageViewerというハイレベルな便利クラスも用意されているので、これでいけるならこれで、さらにカスタマイズが必要なときにvtkImageCanvasSource2Dを使うんだと思われます。vtkImageViewerの例を次にやる予定。)

あ゛ー、どっから手をつけていいかすらわからん。というわけでグーグル先生に”numpy texture vtk”とお伺いを立てる。

ふむふむ、一番上の検索結果になにやら参考になりそうな話題が。

まずは、8ビットの符号なし整数型でグレースケールの画像をテケトーに作って

h,w = 48,64
data_matrix = np.random.randint(0,255,(h,w)).astype(np.uint8)

これを

dataImporter = vtk.vtkImageImport()
dataImporter.CopyImportVoidPointer(data_matrix, data_matrix.nbytes)

のようにvtkImageImportオブジェクトを使って変換する。vtkImageImportはnumpy対応らしいので、tostringとかしなくていいらしい。

あとはデータタイプを8ビットの符号なし整数型と指定する。

dataImporter.SetDataScalarTypeToUnsignedChar()
dataImporter.SetNumberOfScalarComponents(1)

これをやらないとたぶん32ビットと解釈されるっぽく、ドットが連続じゃなくて3ピクセルくらいのギャップができてしまった。

その上でデータの範囲を指定

dataImporter.SetDataExtent(0, h-1, 0, w-1, 0, 0)
dataImporter.SetWholeExtent(0, h-1, 0, w-1, 0, 0)

SetDataExtentの方はバッファーされる実際に表示される領域で、SetWholeExtentの方は全体のことらしい。

こうしてできたdataImporterオブジェクトをテクスチャーとして指定する。

texture = vtk.vtkTexture()
texture.SetInputConnection( dataImporter.GetOutputPort() )

あとは前回のコードそのままで表示された。

Random_img_in_vtk

ふーむ。なんとかなってきた。カメラがいつも引いたままなのでぴったりズームするようにしたい。

メーリングリストの方にSetParallelScaleを高さにすると書いてあるが、

renderer.GetActiveCamera().SetParallelScale(h)

と、やってみたが、なんか違う。。。

と思って調べてみたらvtkImageViewerという便利なクラスがあるらしいのを今更発見。多分これでいいじゃん。

一応今回のコードも全部載せておきます。vtkImageViewerつかった方がスマートでしょうけど、ローレベルにはどうやるかという意味でまったく無駄ではなかった・・・と思いたい。いやいやnumpyアレイの変換とかいづれ必要だし、いいのだ。

from __future__ import division

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


class Test(wx.Frame):

    def __init__ (self, imgsize):

        h,w = imgsize # data array dimension (h,w)
        self.imgsize = imgsize

        wx.Frame.__init__(self, None, title='TextureMapQuad')

        canvas = wx.Panel(self, size=(w,h))
        rwi = wxVTKRenderWindow(canvas, -1)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(canvas, 1, wx.EXPAND)
        self.SetSizerAndFit(sizer)

        rwi.Enable(True)
        self.SetupRender()
        rwi.GetRenderWindow().AddRenderer(self.ren)

        self.Layout()
        self.Show()

    def SetupRender(self):

        h,w = self.imgsize

        points = vtk.vtkPoints()
        points.InsertNextPoint(0.0,0.0,0.0)
        points.InsertNextPoint(w/h,0.0,0.0)
        points.InsertNextPoint(w/h,1.0,0.0)
        points.InsertNextPoint(0.0,1.0,0.0)

        polygon = vtk.vtkPolygon()
        polygon.GetPointIds().SetNumberOfIds(4)
        polygon.GetPointIds().SetId(0,0)
        polygon.GetPointIds().SetId(1,1)
        polygon.GetPointIds().SetId(2,2)
        polygon.GetPointIds().SetId(3,3)

        polygons = vtk.vtkCellArray()
        polygons.InsertNextCell(polygon)

        quad = vtk.vtkPolyData()
        quad.SetPoints(points)
        quad.SetPolys(polygons)

        textureCoordinates = vtk.vtkFloatArray()
        textureCoordinates.SetNumberOfComponents(3)
        textureCoordinates.SetName("TextureCoordinates")
        textureCoordinates.InsertNextTuple( (0.0, 0.0, 0.0) )
        textureCoordinates.InsertNextTuple( (w/h, 0.0, 0.0) )
        textureCoordinates.InsertNextTuple( (w/h, 1.0, 0.0) )
        textureCoordinates.InsertNextTuple( (0.0, 1.0, 0.0) )
        quad.GetPointData().SetTCoords(textureCoordinates)

        # 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, h-1, 0, w-1, 0, 0)
        dataImporter.SetWholeExtent(0, h-1, 0, w-1, 0, 0)

        # set the imported array as texture
        texture = vtk.vtkTexture()
        texture.SetInputConnection( dataImporter.GetOutputPort() )

        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInput(quad)  # vtk 5.1.0

        texturedQuad = vtk.vtkActor()
        texturedQuad.SetMapper(mapper)
        texturedQuad.SetTexture(texture)

        renderer = vtk.vtkRenderer()
        renderer.AddActor(texturedQuad)
        renderer.SetBackground(1,1,1)

        self.ren = renderer


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

« wxpythonとvtkでビデオプレーヤー作ってみる。その1。C++のJpeg表示サンプルをPythonに翻訳。 | トップページ | wxpythonとvtkでビデオプレーヤー作ってみる。その3。vtkImageViewerでjpeg表示。 »

Python」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

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

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1169291/52094935

この記事へのトラックバック一覧です: wxpythonとvtkでビデオプレーヤー作ってみる。その2。numpyアレイで用意した2Dテクスチャを四角ポリゴンに貼る。:

« wxpythonとvtkでビデオプレーヤー作ってみる。その1。C++のJpeg表示サンプルをPythonに翻訳。 | トップページ | wxpythonとvtkでビデオプレーヤー作ってみる。その3。vtkImageViewerでjpeg表示。 »

広告欄


やっつけタイムライン

広告欄

はてブ

人目の訪問です。

  • follow us in feedly

    かなり更新が不定期なため、RSSリーダーをオススメします。現在Feedlyに122人登録頂いています。多謝!RSSを表示

    ブログランキング用 にほんブログ村 IT技術ブログ Pythonへ ブログランキングならblogram






    Jenny Mayhem
2017年11月
      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    

IT技術注目記事

無料ブログはココログ