使用したライブラリ
【画像処理100本ノック】独自の画像入出力クラスを作る
【画像処理100本ノックに挑戦】独自の行列クラスを作る
Q.30. アフィン変換(回転)
(1)アフィン変換を用いて、反時計方向に30度回転させよ。
(2) アフィン変換を用いて、反時計方向に30度回転した画像で中心座標を固定することで、なるべく黒い領域がなくなるように画像を作成せよ。 (ただし、単純なアフィン変換を行うと画像が切れてしまうので、工夫を要する。)
そんなに難しくないです。コードはひどいですが。
int main()
{
const double pi = 3.141592653589793;
double theta = -pi / 6.;
PPM ppm("imori.pnm");
int width = ppm.Get_width();
int height = ppm.Get_height();
double a=cos(theta), b=-sin(theta), c=sin(theta), d=cos(theta), tx=0, ty=0;
Matrix A(2, 2);
A.set({
d/(a*d-b*c),-b/(a*d-b*c),
-c / (a * d - b * c),a / (a * d - b * c)
});
Matrix X2(2);
X2.set({
(double)width/2.,
(double)height/2.
});
Matrix X0 = A * X2;
tx =-(width/2- X0(0, 0));// -tx;
ty =-(height/2- X0(1, 0));
int Width = width;
int Height = height;
PPM ppm2(Width, Height);
for(int i=0; i<Width; i++)
for (int j = 0; j < Height; j++)
{
ppm2(i, j, 'r') = 0;
ppm2(i, j, 'g') = 0;
ppm2(i, j, 'b') = 0;
}
for(int i=0; i<Width; i++)
for (int j = 0; j < Height; j++)
{
Matrix X2(2);
X2.set({
(double)i,
(double)j
});
Matrix X0 = A * X2;
int i0= X0(0, 0)-tx;
int j0 = X0(1, 0)-ty;
if (0 <= i0 && i0 < width && 0 <= j0 && j0 < height)
{
ppm2(i, j, 'r') = ppm(i0, j0, 'r');
ppm2(i, j, 'g') = ppm(i0, j0, 'g');
ppm2(i, j, 'b') = ppm(i0, j0, 'b');
}
}
ppm2.Flush("out.ppm");
return 0;
}