アフィン変換と画像補間法を使えば、画像を拡大・縮小・回転・平行移動することができます。前回紹介したアフィン変換のプログラムを使い、画像を拡大・縮小・回転・平行移動するC言語プログラムを紹介します。
画像を拡大縮小などを行う場合、画像上のピクセル間を補間をする必要になります。そうしないと、拡大後のピクセル間が真っ黒になってしまったり、隣接するピクセル間がガタガタになってしまう問題が生じます。
アフィン変換で画像のピクセルを座標変換したときも同じで、補間をする必要があります。ここでの補間法は前に紹介した、線形補間を使います。
原画像

アフィン変換(移動・拡大・縮小・回転)+線形補間した画像

C言語プログラムは下記のようになります。
すべてのピクセルについて、座標変換を行った後、周りのピクセル値で線形補間しています。
アフィン変換のコードと画像保存やメモリ確保のコードは、紹介済みなので省略します。
下記URLよりダウンロード可能です。
// C言語によるアフィン変換+線形補間で画像拡大縮小回転移動
#include "stdafx.h" // VisualStudio2008でCプログラムを作成するのに必要
#include <malloc.h> // malloc/callocといった動的メモリ確保のために必要
#include <math.h> // 数学関数を使用するためのヘッダ
#include <iostream>
using namespace std; // VisualStudio2008でCプログラムを作成するのに必要
using namespace System;
#define WIDTH 256
#define HEIGHT 256
#define PI 3.1415
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
メモリ確保、画像保存部分
(省略、下記URLから全コードをダウンロードできます。)
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
アフィン変換プログラム部分
(前回紹介したので省略、
下記URLから全コードをダウンロードできます。)
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
// 2次元データの線形補間
unsigned char Interpolation2D(
unsigned char** data, int width, int height, double x, double y)
{
// dataの外なら0を返す
if (x < 0 || x >= width - 1 ||
y < 0 || y >= height - 1)
{
return 0;
}
// 隣接座標取得
int x1 = (int)x;
int x2 = (int)x + 1;
int y1 = (int)y;
int y2 = (int)y + 1;
double s1 =
(data[y1][x2] - data[y1][x1]) * (x - x1) + data[y1][x1];
double s2 =
(data[y2][x2] - data[y2][x1]) * (x - x1) + data[y2][x1];
double s3 = (s2 - s1) * (y - y1) + s1;
if (s3 > 255)
{
return 255;
}
else if (s3 < 0)
{
return 0;
}
else
{
return (unsigned char)s3;
}
}
int main(array<System::String ^> ^args)
{
int i,j;
double** matrix;
double cx;
double cy;
double cz;
// 画像読み込み
unsigned char** data = LoadRawImage("test.raw", WIDTH, HEIGHT);
unsigned char** outdata = GetUCharArrayMemory(WIDTH, HEIGHT);
// 座標変換
for (i = 0; i < HEIGHT; i++)
{
for (j = 0; j < WIDTH; j++)
{
// 10度回転
matrix = SetMatrixZRotate(10);
ConvertCoordinate(matrix, j, i, 0, &cx, &cy, &cz);
// 拡大縮小
matrix = SetMatrixScale(1.5, 0.5, 1);
ConvertCoordinate(matrix, cx, cy, cz, &cx, &cy, &cz);
// 平行移動
matrix = SetMatrixTranslate(-10, 20, 0);
ConvertCoordinate(matrix, cx, cy, cz, &cx, &cy, &cz);
// 変換した座標の線形補間からピクセル値を求める
outdata[i][j] = Interpolation2D(data, WIDTH, HEIGHT, cx, cy);
}
}
// 画像保存
SaveRawImage("outimage.raw", outdata, WIDTH, HEIGHT);
return 0;
}
ちなみにC#で書くと
http://colnagow61s.me.land.to/image_geometry_transform.zip
ソースコードを置いておきます。
| 詳解 画像処理プログラミング C言語で実装する画像処理アルゴリズムのすべて | |
![]() | 昌達 慶仁 ソフトバンククリエイティブ 2008-03-27 売り上げランキング : 5054 おすすめ平均 ![]() とてもわかりやすくて、多くのアルゴリズムを網羅しています。Amazonで詳しく見る |
| 新版 明解C言語 入門編 | |
![]() | 柴田望洋 ソフトバンククリエイティブ 2004-08-28 売り上げランキング : 1324 おすすめ平均 ![]() 満足 見易さ・解説の徹底具合 十分明解だが…Amazonで詳しく見る |
この記事のトラックバックURL
http://thorshammer.blog95.fc2.com/tb.php/249-6740cf0e
この記事にトラックバックする(FC2ブログユーザー)
この記事にトラックバックする(FC2ブログユーザー)
この記事へのトラックバック




十分明解だが…