本サイトは、マルチコア トータルソリューションカンパニー -フィックスターズの技術者有志が運営するサイトです。

2.9 演習問題 (2-4) グレースケール変換プログラム

出典: PS3 Linux Information Site / Cell/B.E.のパワーを体験しよう

 演習問題 (2-4) は、第2章で学習した内容全体の理解度を確認するための総合問題です。

【問題】

 出題プログラム (2-4) は、カラー画像をグレースケール画像に変換するプログラムです。掲載されているrgb2y()関数は、このプログラムの一部で、グレースケール変換をおこなう関数です。この関数をSIMD演算を用いて計算するように書き換えなさい。

 「グレースケール変換」とは、カラー画像を構成する各画素のRGB値から輝度Y (画素の明るさ) のみを抽出したグレースケール (白黒階調の) 画像へと変換することです。輝度Yは、以下の式で算出されます。

(輝度の算出式) fY(R, G, B) = R × 0.29891 + G × 0.58661 + B × 0.11448

画像:FIGURE-02-24.png

図 2.24 グレースケール変換

 rbg2y()関数の第1引数srcと第2引数dstには、それぞれ入力バッファ (カラー画像) と出力バッファ (グレースケール画像) へのポインタの値が格納されています。第3引数numには、処理される画素数が渡されます。

 rgb2y()関数に渡される入力データは、図 2.25 (a) に示すようなデータフォーマットになっています。また、グレースケール変換した結果は、図 2.25 (b) に示すようなデータフォーマットで出力されます。

画像:FIGURE-02-25.png

図 2.25 データフォーマット

 また、浮動小数点演算の誤差によりRGB値の桁溢れが生じないように最大値255で丸め込みをおこなっています。


【出題プログラム (2-4)】

 1 void rgb2y(unsigned char *src, unsigned char *dst, int num)
 2 {
 3     int i;
 4     float r, g, b, y;
 5     float rconst = 0.29891f;
 6     float gconst = 0.58661f;
 7     float bconst = 0.11448f;
 8     unsigned int max = 255;
 9 
10     for (i = 0; i < num; i++) {
11         r = (float) src[i * 4];
12         g = (float) src[i * 4 + 1];
13         b = (float) src[i * 4 + 2];
14 
15         y = r * rconst + g * gconst + b * bconst;
16 
17         if (y > max) {
18             y = max;
19         }
20 
21         dst[i * 4] = dst[i * 4 + 1] = dst[i * 4 + 2] = (unsigned char) y;
22     }
23 
24     return;
25 }

⇒出題プログラム (2-4) のソースコードはこちらから


【解答方針】

 この問題は、これまでの例題および演習問題のすべてのトピックを盛り込んでいます。まず、輝度Yの計算では、unsigned char型で与えられたRGB値をfloat型に変換し浮動小数点計算をしなくてはなりません。また、浮動小数点計算の誤差の丸め込みには、条件分岐の削除をおこなわければなりません。これらのポイントを押さえて、SIMD演算を用いたプログラムに書き換えなさい。

 以下のポイントに従って解答プログラムを作成するとよいでしょう。

 (1) SIMD演算しやすいように、R (赤)、G (緑)、B (青)の要素ごとにデータを並べ替えます。
 (2) 輝度の計算は浮動小数点を用いて計算するため、並べ替えたデータをvector unsigned char型からvector float型への変換を行います。演習問題 (2-2) と同じ考え方です。
 (3) 計算の結果得られた輝度Yの値を、出力先バッファに { Y, Y, Y, 0 } の形に並べ替えて出力します。

画像:FIGURE-02-26.png

図 2.26 RGBからグレースケールへの変換


演習問題 (2-3)」へ戻る 第2章目次 演習問題 (2-4) の解答」へ進む
チュートリアル目次
表示
個人用ツール
オープンソースプロジェクト
ツールボックス