デバッグ用の画像データを生成する
画像処理のプログラムを作るときには、わかりやすいデータが格納されているデバッグ用の画像で実施しているコードが正しいか常に確認しなくてはなりません。
その確認作業には風景画像や人物写真を使うべきではありません。所望のアドレスに入っているデータが推測できないからです。(たとえ SIDBA や lenna であっても、使うべきではない )
私のおすすめは下記のような画像です。これらは(X,Y)座標に格納されている値が確実にわかる画像です。
下記のコードはこれらのテストパターンを byte[] データ配列に格納します。引数として与える width と height には 2 のべき乗の数値を与えるのがデバッグに使いやすいです。たとえば 256 とか 512 とか 1024 という値です。
また、width と height は違ったべき乗の値にしておくのが仕事のコツです。たとえば
width = 512;
height = 256;
こういう感じです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace aaa
{
public class ApplicationUtility
{
public ApplicationUtility()
{
}
// べったり同じ色のデータの画像を取得する.
public bool GetDataFill( byte [] data, int width, int height, byte level )
{
int w = width;
int h = height;
int numpix = w * h;
int adrs = 0;
for ( int n = 0; n < numpix; n++ )
{
data[adrs] = level;
adrs++;
}
return true;
}
// 水平ノコギリ波の画像を取得する.
public bool GetDataSawtoothHorz( byte [] data, int width, int height )
{
int w = width;
int h = height;
byte level;
int adrs;
for ( int j = 0; j < h; j++ )
{
level = (byte)(j);
adrs = w * j;
for ( int i = 0; i < w; i++ )
{
data[ adrs ] = level;
adrs++;
}
}
return true;
}
// 垂直ノコギリ波の画像を取得する.
public bool GetDataSawtoothVert( byte [] data, int width, int height )
{
int w = width;
int h = height;
byte level;
int skip = w;
int adrs;
for ( int i = 0; i < w; i++ )
{
level = (byte)(i);
adrs = i;
for ( int j = 0; j < h; j++ )
{
data[ adrs ] = level;
adrs += skip;
}
}
return true;
}
// ななめノコギリ波の画像を取得する.
public bool GetDataSawtoothNaname( byte [] data, int width, int height )
{
int w = width;
int h = height;
byte level;
for ( int j = 0; j < h; j++ )
{
for ( int i = 0; i < w; i++ )
{
level = (byte)( i + j );
data[ i + w * j ] = level;
}
}
return true;
}
// 水平コサインデータの画像を取得する.
public bool GetDataCosWaveHorz( byte [] data, int width, int height, double cycle )
{
int w = width;
int h = height;
double two_pai = 2.0 * Math.PI;
double rate;
double rad;
double tmp0;
double tmp1;
byte level;
byte [] table = new byte[ h ];
const double OFFSET = 1.0;
const double MUL = 0.5;
// テーブルを作る.
for ( int j = 0; j < h; j++ )
{
// ラジアンを算出する.
rate = (double)(j)/(double)( h - 1 );
rad = rate * two_pai;
// ここでコサインの計算をする.
tmp0 = -( Math.Cos( cycle * rad ));
// 0.0 から 1.0 が存在範囲.
tmp1 = (( tmp0 + OFFSET ) * MUL );
// 0 から 255 にキャストする.
level = (byte)( Math.Round( tmp1 * 255.0 ));
table[j] = level;
}
int adrs;
// 水平の cos 波形2D, ( 0 から 1.0 ).
for ( int j = 0; j < h; j++ )
{
level = table[j];
adrs = w * j;
for ( int i = 0; i < w; i++ )
{
data[ adrs ] = level;
adrs++;
}
}
return true;
}
// 垂直コサインデータの画像を取得する.
public bool GetDataCosWaveVert( byte [] data, int width, int height, double cycle )
{
int w = width;
int h = height;
double two_pai = 2.0 * Math.PI;
double rate;
double rad;
double tmp0;
double tmp1;
byte level;
byte [] table = new byte[ w ];
const double OFFSET = 1.0;
const double MUL = 0.5;
// テーブルを作る.
for ( int i = 0; i < w; i++ )
{
// ラジアンを算出する.
rate = (double)(i)/(double)( w - 1 );
rad = rate * two_pai;
// ここでコサインの計算をする.
tmp0 = -( Math.Cos( cycle * rad ));
// 0.0 から 1.0 が存在範囲.
tmp1 = (( tmp0 + OFFSET ) * MUL );
// 0 から 255 にキャストする.
level = (byte)( Math.Round( tmp1 * 255.0 ));
table[i] = level;
}
int adrs;
// 垂直の cos 波形2D, ( 0 から 1.0 ).
for ( int j = 0; j < h; j++ )
{
adrs = w * j;
for ( int i = 0; i < w; i++ )
{
data[ adrs ] = table[i];
adrs++;
}
}
return true;
}
// 水平垂直加算コサインデータの画像を取得する.
public bool GetDataCosWaveHorzVert( byte [] data, int width, int height, double cycle )
{
int w = width;
int h = height;
double two_pai = 2.0 * Math.PI;
double rate;
double rad;
double tmp;
double [] table_for_a = new double[ h ];
double [] table_for_b = new double[ w ];
const double OFFSET = 1.0;
const double MUL = 0.5;
// テーブルを作る.
for ( int j = 0; j < h; j++ )
{
// ラジアンを算出する.
rate = (double)(j)/(double)( h - 1 );
rad = rate * two_pai;
// ここでコサインの計算をする.
tmp = -( Math.Cos( cycle * rad ));
// 0.0 から 1.0 が格納される.
table_for_a[j] = (( tmp + OFFSET ) * MUL );
}
// テーブルを作る.
for ( int i = 0; i < w; i++ )
{
// ラジアンを算出する.
rate = (double)(i)/(double)( w - 1 );
rad = rate * two_pai;
// ここでコサインの計算をする.
tmp = -( Math.Cos( cycle * rad ));
// 0.0 から 1.0 が格納される.
table_for_b[i] = (( tmp + OFFSET ) * MUL );
}
double a;
double b;
byte level;
int adrs;
for ( int j = 0; j < h; j++ )
{
// 0.0 から 1.0 の範囲をとる.
a = table_for_a[j];
adrs = w * j;
for ( int i = 0; i < w; i++ )
{
// 0.0 から 1.0 の範囲をとる.
b = table_for_b[i];
// 両方を加算すると 0.0 から 2.0 の範囲をとる.
tmp = a + b;
// 0 から 255 の byte 区間にマッピングする.
level = (byte)( Math.Round(( tmp * 0.5 ) * 255.0 ));
// 8bits画像データとして格納する.
data[ adrs ] = level;
adrs++;
}
}
return true;
}
// 水平グラデーションデータの画像を取得する.
public bool GetDataGradHorz( byte [] data, int width, int height )
{
int w = width;
int h = height;
byte level;
double rate;
int adrs;
for ( int j = 0; j < h; j++ )
{
rate = (double)(j)/(double)( h - 1 );
level = (byte)( Math.Round( rate * 255.0 ));
adrs = w * j;
for ( int i = 0; i < w; i++ )
{
data[ adrs ] = level;
adrs++;
}
}
return true;
}
// 垂直グラデーションデータの画像を取得する.
public bool GetDataGradVert( byte [] data, int width, int height )
{
int w = width;
int h = height;
byte level;
double rate;
int skip = w;
int adrs;
for ( int i = 0; i < w; i++ )
{
rate = (double)(i)/(double)( w - 1 );
level = (byte)( Math.Round( rate * 255.0 ));
adrs = i;
for ( int j = 0; j < h; j++ )
{
data[ adrs ] = level;
adrs += skip;
}
}
return true;
}
// ななめグラデーションデータの画像を取得する.
public bool GetDataGradNaname( byte [] data, int width, int height )
{
int w = width;
int h = height;
double value_i;
double value_j;
double rate_x;
double rate_y;
byte level;
int adrs;
for ( int j = 0; j < h; j++ )
{
rate_y = (double)(j)/(double)( h - 1 );
value_j = ( rate_y * 127.0 );
adrs = w * j;
for ( int i = 0; i < w; i++ )
{
rate_x = (double)(i)/(double)( w - 1 );
value_i = ( rate_x * 128.0 );
level = (byte)( Math.Round( value_i + value_j ));
data[ adrs ] = level;
adrs++;
}
}
return true;
}
}
}
サンプルソースを用意しました。上記のコードのコピーペーストでうまく動かない場合にご利用ください。
デバッグ用の画像データを生成する
1 ファイル 14 KB