● ToolBox API徒然草(2006/08/16)

  このニュースは、MOSAの会員にのみ配布されているデベロッパー向けの
  デジタルマガジンMOSADeNのに掲載された記事です。ほぼ一ヶ月遅れで
  ここに掲載されて行きます

 〜 アプリケーションのUniversal Binary化(その11) 〜


今回は、前回紹介した幾つかのトピックスのうち、画像フィルタ処理などに活用することができるvImage.frameworkのルーチンを、例題を示しながら解説してみます。PowerPCのAltiVecコードをIntel CPUのSSE/SSE2コードに変換する作業とは直接関係ありませんが、vImageルーチン(API)を使うことは処理速度の向上において重要なテクニックです。

前回も紹介しましたが、vImage.frameworkの詳細については、以下のドキュメントを参照してください。

「Optimizing Image Processing With vImage」「vImage.pdf」(PDF 366ページ)

http://developer.apple.com/documentation/Performance/Conceptual/vImage/index.html

ドキュメントのタイトル通り、vImage.frameworkは各種画像処理に関係するルーチンを提供しています。各ルーチンはPowerPC版であればAltiVecコードを、Intel CPU版であればSSE/SSE2コードを最大限用いることで最適化されています。よって、vImage.frameworkを上手に活用すれば、かなり特殊なケースを除き、自分自身でAltiVecやSSE/SSE2を使うことなく多くの画像処理を高速化することが可能となります。

vImage.frameworkには200近いルーチンが存在しているのですが、それぞれのルーチンは用途別に以下の7つのグループに分類されています。

(1)Convolution
(2)Morphological Operations
(3)Geometric Operations
(4)Histogram Operations
(5)Alpha Compositing Operations
(6)ImageTransformation Operations
(7)Conversion Operations

Convolutionは畳み込み演算のことでして、ぼかし、シャープネス、エッジ強調といった画像に対して各種フィルタ処理を実行できます。入力画像の全ピクセルに対し、そのピクセルを中心としたピクセル領域(3x3とか5x5など)とカーネル係数との掛け合わせを行います。Morphological Operationsは、グレースケール画像に対し画像の細線化や膨らまし処理を実行します。Geometric Operationsは、画像領域に対してAffine変換を実行することで、画像の回転、反転、歪みなどを実現します。Histogram Operationsでは、ヒストグラム処理により、階調やコントラストなどを制御することが可能です。Alpha Compositing Operationsはα値(透明度)による画像合成を行い、ImageTransformation Operationsでは画像のガンマ値調整などが行えます。最後のConversion Operationsは、画像タイプの各種変換(ARGBからグレースケールなど)に利用します。

vImageルーチンが画像に対してどのような効果を発揮するのか?また、どのようなソースコードを記述をすれば最適なのかは、Developerフォルダの以下の場所に「Tableau」というサンプル(Xcodeプロジェクト)がありますので、これを参照してください。vImageルーチンによる画像処理の速度と、その効果を一通り確認することが可能です。

/Developer/Examples/Accelerate/vImage/Tableau

vImageで利用できる画像タイプは以下の4種類です。

また、vImageルーチンで利用する画像バッファはvImage_Buffer構造体として以下のように定義されています。vImagePixelCountとsize_tは、両方ともunsigned longです。

以下に、vImage_Buffer用メモリ領域を確保するルーチンと解放する簡単なルーチンを紹介しておきます。ちなみに、ルーチン内のmalloc()とfree()は、NewPtr()とDisposePtr()に差し替えても問題ありません。

以下のsharpnessCGImage()は、フルカラーバッファ(ARGB)に保存されたグレースケール画像を浮動小数点グレースケール画像まで変換し、シャープネスを調整してから、再度フルカラーバッファに戻すサンプルルーチンです。各バッファのメモリ領域やRowByte値は処理する直前にvImage_Bufferに確保し、そのポインタの配列を引数で渡しています。

vImageのルーチンはすべてスレッド・セーフですので、目的の画像処理ルーチンをマルチプロセッサに対応させれば、処理をさらに高速化することが可能です。具体的に言えば、ある画像の矩形領域をプロセッサ数(2つなら上下半分)に分けて、それぞれに対して別スレッドでvImagekルーチンを用います。そうすれば、単純計算で2倍(実際はもう少し遅くなりますが)の処理速度を得ることができるわけです。

次回は、本格的にAltiVecからSSE/SSE2コードへの変換作業の話となります。幾つかの例題を取り上げて、やっかいなコード変換作業について解説する予定です。


copyright 2006 Ottimo, Inc. All rights reserved
無断転載・引用禁止
Contact us: koike@ottimo.co.jp