2011/02/16

Android NDKでグレースケール化プログラムを作る

今日はAndroid NDKをいじっていました。

OpenCVで画像処理をするためには、Java側から画像データを渡す必要があります。
(カメラの画像、SDカードに保存した画像などなど)

ビットマップをネイティブに渡すには、GetPixelsを使って、int配列に変換してから渡すようです。

以下の記事に、Javaからネイティブにビットマップデータを渡すやり方が書いてあったので、参考にしてプログラムを書いてみました。

NDKを使って、nativeに処理をさせる@Tech Booster

コードを色々といじって分かったのですが、Android側でGetPixelsを使ってビットマップの配列データを取得すると、1ピクセルあたり4バイトのデータが出来上がるようです。

リファレンスを見ると、
GetPixels Returns in pixels[] a copy of the data in the bitmap. Each value is a packed int representing a Color.
となっているので、元のビットマップの形式に関係なく、4バイトのColor型に変換されて出てくると理解して良さそうです。

GetPixcelsを使ってint配列を取り出し、ネイティブに渡すことができたので、次はRGBへの分離を行います。

intからR、G、Bチャネルのデータを取り出すコードは下記のとおりです。

//4バイトのintから、R,G,Bのチャネルを取り出す
int r,g,b,result;
r = bmpColors[cnt]&0x00FF0000;
r = r >>16;//右に16ビットシフト
g = bmpColors[cnt]&0x0000FF00;
g = g >>8;//右に8ビットシフト
b = bmpColors[cnt]&0x000000FF;

//この後処理をする

//戻す
result=(r<<16)|(g<<8)|b;



これで渡されたものを、何もしないで元に戻すことができるようになりました。
上が元のBitmap、下がCの関数を通ってきたBitmap















次はカラーをグレースケールに変換してみましょう。

グレースケールに変換する公式は、
Y=(R*0.29891+ G*0.58661+ B*0.11448);
のようなので、早速実装してみます。

//
//グレースケールの公式
float fY=(r*0.29891+ g*0.58661+ b*0.11448);
int Y=trunc(fY);
//グレースケールでもどす
int result = (Y<<16) | (Y << 8) | Y;

グレースケールにしたものが下記の画像となります。















画像の渡し方がわかったので、次はOpenCVのソースコードを組み込む方法を調べていきたいと思います。

ではまた。

0 件のコメント:

コメントを投稿