線形補間の最適化で2点間の距離を256にすると書きましたが、これを実際のプログラムで実現しようと思います。
基本アルゴリズムの最適化のところでSIN,COSの値に1024を掛けて整数値に変換して処理をしました。
これを用いて計算します。
サンプルプログラムを以下に示します。
//dx, dy : 求めたい2点間の距離
//int_sin, int_cos : SIN,COSの値に1024を掛けた値
//x1, y1 : 入力画像位置に1024を掛けた値
//x2, y2 : 出力画像位置
//SrcCX, SrcCY : 入力画像中心座標
//DstCX, DstCY : 出力画像中心座標
x1 = ((x2-DstCX) * int_cos - (y2-DstCY) * int_sin) + (SrcCX << 10);
y1 = ((x2-DstCX) * int_sin + (y2-DstCY) * int_cos) + (SrcCY << 10);
dx = (x1 >> 2) - ((x1 >> 10) << 8);
dy = (y1 >> 2) - ((y1 >> 10) << 8);
|
これで線形補間に用いる2点間の距離を計算できますがもう少し簡単化できます。そのリストを以下に示します。
x1 = ((x2-DstCX) * int_cos -
(y2-DstCY) * int_sin) + (SrcCX << 10);
y1 = ((x2-DstCX) * int_sin + (y2-DstCY) * int_cos) + (SrcCY << 10);
dx = (x1 - (x1 & 0xfffffc00)) >> 2;
dy = (y1 - (y1 & 0xfffffc00)) >> 2; |
これらを用いた線形補間を用いた回転のサンプルプログラムを以下に示します(メインルーチン部分だけ)。
// pSrcImg : 入力画像
// pDstImg : 出力画像
// SrcWidth, SrcHeight : 入力画像幅高さ
// DstWidth, DstHeight : 出力画像幅高さ
// A : 角度(ラジアン)
// ValSin, ValCos : 指定角度のSIN,COS値
// x, y : 入力画像内の位置に1024を掛けた値
// x1, y1 : 入力画像内の位置
// x2, y2 : 出力画像内の位置
// SrcCX, SrcCY : 入力画像の中心座標
// DstCX, DstCY : 出力画像の中心座標
// int_cos, int_sin : 指定角度のSIN,COS値の整数値
//2次元線形補間用マクロ
#define SET_LINER_BYTE(D, dx, dy, C0, C1, C2, C3) {\
unsigned char Top, char Bottom;\
Top = pluTBL[(C0<<8)+(255-dx)] + pluTBL[(C1<<8)+dx];\
Bottom = pluTBL[(C2<<8)+(255-dx)] + pluTBL[(C3<<8)+dx];\
D = pluTBL[(Top<<8)+(255-dy)] + pluTBL[(Bottom<<8)+dy];\
}
//画像回転処理メインルーチン
//出力画像の座標でループを行う
for(y2=0; y2 < DstHeight; y2++) {
for(x2=0; x2 < DstWidth; x2++) {
//入力画像の位置に1024を掛けた値を計算
x = ((x2-DstCX) * int_cos - (y2-DstCY) * int_sin) + (SrcCX
<< 10);
y = ((x2-DstCX) * int_sin + (y2-DstCY) * int_cos) + (SrcCY
<< 10);
//入力画像位置を計算
x1 = x >> 10;
y1 = y >> 10;
//x1, y1がともに入力画像の有効範囲にあれば出力へコピーを行う
if( x1 >= 0 && x1 < SrcWidth-1
&& y1 >= 0 && y1 < SrcHeight-1
) {
//2点間の距離を計算
dx = (x - (x & 0xfffffc00)) >> 2;
dy = (y - (y & 0xfffffc00)) >> 2;
//線形補間を掛けてその結果をpDstImg[y2][x2]へ格納する
SET_LINER_BYTE(pDstImg[y2][x2], dx, dy,
pSrcImg[y1][x1], pSrcImg[y1][x1+1],
pSrcImg[y1+1][x1], pSrcImg[y1+1][x1+1]);
}
}
}
|
このプログラムでは画像の端のエッジを取り除くことはできません。これを回避するためには条件判定文が追加で必要です。各自考えてみてください。
2000/08/21 サンプルプログラム中のバグを修正しました。
TOP
|