template.zip | 76c743b6b19991afcbbbeec7a82ffa92 |
template.c | b91514f0ceeb6aae00c4d016952e0eb5 |
int image_processing_program( int **s, int **d, int **w, int **t, int **g, int **b, int lx, int ly ){
(void)s; (void)d; (void)w; (void)t; (void)g; (void)b; (void)lx; (void)ly; //未使用変数の警告回避用
//////////////////////////////////////////////////////////////
// - s: 入力画像(カラー画像 or ネガ画像:輝度反転画像)BMP互換のPIXEL形式
// - d: 出力画像(処理結果)
// - w, t, g, b: 作業用ワーク領域(必要に応じて自由に使用可)
// t: カラー画像から、グレー画像データに変換したBMPファイル形式データ
// g: カラー画像から、グレー画像データに変換した値、演算処理用
// b: グレー画像データを更に、128以上、以下で 255,0 に二値化したデータ
// PROCESS_ALL_PIXELS lx X ly で構成される全ての画素に対する操作
// 0xC0C0C0 は、処理の確認用。 本来は、0xFFFFFF で対処物と穴は同色にする
PROCESS_ALL_PIXELS { t[y][x] = 255 - b[y][x]; d[y][x] = b[y][x] ? 0xC0C0C0 : 0; }
int background = labeling( t, w, lx, ly, 4 ); // 4連結のラベリング (対象物が8連結)
// 2次元行列 gのデータ領域は、lx*ly の連続領域として確保されている。
int *lut=&g[0][0];
for(int e=0; e<=background; e++ )lut[e]=e;
// 縁に接続している要素の破棄
for(int t=ly-1, x=0;x<lx;x++){ lut[w[0][x]]=0; lut[w[t][x]]=0; }
for(int t=lx-1, y=0;y<ly;y++){ lut[w[y][0]]=0; lut[w[y][t]]=0; }
PROCESS_ALL_PIXELS w[y][x] = lut[w[y][x]] ? 0xFFFFFF : 0 ; // 穴部分 B:0xFF, G:0xFF, R:0xFF
image_or( d, w, d, lx, ly ); // 画像間での or 処理、画素単位
save_without_conversion = 1; // データの無変換保存モード dのデータは、BMP画像形式で保持済み
return 0;
}
カテゴリ | 機能 | 概要 | 関連関数/マクロ | 備考 |
---|---|---|---|---|
画像処理 | BMPファイル読み込み | 32ビットBMP画像を読み込む | stbi_load | stb_image.h 依存、 main 内で使用 |
BMPファイル保存 | 32ビットBMP形式で画像を保存 | saveDataAsBMP32 , saveArray2bmp32 | マクロで簡易呼び出し可能 | |
ラベルデータ保存 | ラベリング結果をバイナリファイルに保存 | save_label_data | バイナリ形式で効率的 | |
2次元フーリエ変換 | DFT/FFTおよびIDFT/IFFTをサポート | fourierTransform , ft_size_check , interchange2D | 2のべき乗サイズでFFT使用 | |
パワースペクトル | フーリエ変換結果をグレースケールで可視化 | PowerSpectrum | 対数スケールで正規化 | |
ホモグラフィ変換 | 4点対応で画像変換、マスク対応 | Homography , HomographyCore ,
HomographyTrans , HomographyTransMask | 並列化対応 | |
畳み込み処理 | ゼロパディング付き整数/浮動小数点畳み込み | convolution , convolution_float | 任意カーネルサイズ対応 | |
連結成分ラベリング | 4/8連結ラベリング(Union-Find使用) | labeling , uf_init , uf_find , uf_union , uf_free , uf_count_labels | ラベル数をカウント | |
グレースケール変換 | RGB画像をグレースケールに変換 | main 内の計算 | YUV係数(306, 601, 117)使用 | |
疑似カラー変換 | 整数値をRGBカラーにマッピング | int2PseudoColor , image_pc | ビット単位で色生成 | |
ピクセル値クランプ/正規化 | 整数値を0~255にクランプまたは正規化 | int2PIXEL , int2PIXEL_adjust , clamp_and_convert , rgb2PIXEL_adjust | 自動正規化オプション対応 | |
RGBチャンネル操作 | RGBチャンネルの分離と統合 | image_PIXEL2rgb , image_rgb2PIXEL | 並列化対応 | |
基本画像演算 | コピー、ビット演算(NOT, AND, OR, XOR)、
算術演算(加減乗除)、絶対値加算 | image_set , image_copy , image_not , image_and , image_or ,
image_xor , image_add , image_sub , image_mul , image_div ,
image_add_abs3 | ピクセル単位の高速処理 | |
行列演算 | LU分解 | ピボット選択付きLU分解 | lu_decomposition | 行列分解の基盤 |
連立方程式解法 | LU分解を用いた解法 | solve_LU | ホモグラフィなどで使用 | |
逆行列計算 | LU分解を用いた逆行列 | inverse_matrix | 並列化対応 | |
行列積 | 2つの行列の積を計算 | multiplication_matrix | 並列化対応 | |
行列ダンプ | 行列データをフォーマット出力 | dump_array | デバッグ用 | |
描画 | 直線描画 | Bresenhamアルゴリズムで直線描画(通常/XOR) | DrawLine , DrawLineExor | XORモードで重ね書き可能 |
ポリライン描画 | 複数点の線分描画(閉形状対応) | DrawPolyline | 図形描画の基礎 | |
円描画 | 中心と半径で円を描画 | DrawCircle | Bresenhamアルゴリズム | |
円弧描画 | 指定角度範囲の円弧を描画 | DrawArc | 角度範囲を正規化 | |
楕円描画 | 2点指定で楕円を描画 | DrawEllipse | ステップ角度で近似 | |
並列処理 | OpenMP並列化 | フーリエ変換、畳み込み、行列演算などで並列化 | #pragma omp parallel for | 複数関数で使用 |
スレッド数制御 | 最大スレッド数を指定 | argumentAnalysis ( -t オプション) | omp_set_num_threads 使用 | |
補助機能 | 2次元配列確保 | 連続メモリで2次元配列を割り当て | alloc2D , alloc2Darray | メモリ効率的 |
高精度タイマー | マイクロ秒単位の時間計測 | get_micro_time , print_elapsed_time | Windows/Unix対応 | |
複素数演算 | 加減乗除、回転因子生成 | RotorCOMPLEX , AddCOMPLEX , SubCOMPLEX , MulCOMPLEX ,
ImeDivCOMPLEX , ImeMulCOMPLEX , AppendCOMPLEX | フーリエ変換で使用 | |
コマンドライン解析 | 入力/出力ファイル、各種オプション処理 | argumentAnalysis | -v , -V , -n , -a , -t 対応 | |
デバッグ出力 | 関数名と行番号の出力 | HERE | 詳細モード( verbose )対応 | |
データ構造 | ピクセル構造体 | BGRA/RGBA形式のピクセル | PIXEL , STBPX | パディング制御 |
BMPヘッダ | BMPファイルヘッダ | HEADER | 32ビットBMP専用 | |
点構造体 | 整数/浮点/倍精度の座標 | POINTi , POINTf , POINTd | ホモグラフィなどで使用 | |
複素数構造体 | 実部と虚部 | COMPLEX | フーリエ変換用 | |
Union-Find | ラベリング用データ構造 | UnionFind | 動的メモリ管理 | |
マクロ | 2次元配列操作 | 型付き2次元配列定義 | v2D , v2Dp , v2Dc , v2Di , v2Df , v2Dd | 型安全性を向上 |
ピクセルループ | 全ピクセルを走査 | PROCESS_ALL_PIXELS | コード簡略化 | |
行列変換 | ホモグラフィ変換の座標計算 | mtxMul | インライン計算 | |
制御構文エイリアス | if , else if , else の代替 | IF , EI
, EE | 可読性に議論あり | |
カスタマイズ | アルゴリズム実装 | ユーザーがカスタム処理を実装 | image_processing_program | 作業バッファ複数提供 |
インクルード利用 | ヘッダファイルとして使用 | TEMPLATES_USE_AS_INCLUDE_FILE | 柔軟な利用形態 |
int saveDataAsBMP32(char *fname, void *b, int lx, int ly);
PIXEL **img = (PIXEL **)alloc2Darray(sizeof(PIXEL), 100, 100);
// imgにデータをセット
saveArray2bmp32("output.bmp", img, 100, 100);
int fourierTransform(COMPLEX **d, int lx, int ly, int flag);
COMPLEX **data = (COMPLEX **)alloc2Darray(sizeof(COMPLEX), 128, 128);
// dataに値をセット
fourierTransform(data, 128, 128, DFT);
void PowerSpectrum(char *fname, COMPLEX **u, PIXEL **a, int lx, int ly);
COMPLEX **freq = (COMPLEX **)alloc2Darray(sizeof(COMPLEX), 128, 128);
PIXEL **img = (PIXEL **)alloc2Darray(sizeof(PIXEL), 128, 128);
PowerSpectrum("spectrum.bmp", freq, img, 128, 128);
void HomographyTrans(PIXEL **c, int lx, int ly, PIXEL **s, int slx, int sly, double inv[3][3]);
PIXEL **src = (PIXEL **)alloc2Darray(sizeof(PIXEL), 100, 100);
PIXEL **dst = (PIXEL **)alloc2Darray(sizeof(PIXEL), 200, 200);
double inv[3][3] = {/* 逆行列データ */};
HomographyTrans(dst, 200, 200, src, 100, 100, inv);
void HomographyTransMask(PIXEL **c, int lx, int ly, PIXEL **s, int slx, int sly, int **mask, double inv[3][3]);
int **mask = (int **)alloc2Darray(sizeof(int), 100, 100);
// maskに値をセット
HomographyTransMask(dst, 200, 200, src, 100, 100, mask, inv);
void Homography(PIXEL **s, int slx, int sly, int **mask, POINTf sp[4], PIXEL **d, int lx, int ly, POINTf dp[4]);
POINTf src_pts[4] = {{0,0}, {100,0}, {100,100}, {0,100}};
POINTf dst_pts[4] = {{10,10}, {190,10}, {190,190}, {10,190}};
Homography(src, 100, 100, NULL, src_pts, dst, 200, 200, dst_pts);
int labeling(int **b, int **labels, int lx, int ly, int connectivity);
int **bin = (int **)alloc2Darray(sizeof(int), 100, 100);
int **labels = (int **)alloc2Darray(sizeof(int), 100, 100);
int num_labels = labeling(bin, labels, 100, 100, 8);
void convolution(int **s, int **d, int lx, int ly, int n, int kernel[n][n]);
int sobelX[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
int **src = (int **)alloc2Darray(sizeof(int), 100, 100);
int **dst = (int **)alloc2Darray(sizeof(int), 100, 100);
convolution(src, dst, 100, 100, 3, sobelX);
void convolution_float(float **s, float **d, int lx, int ly, int n, float kernel[n][n]);
void image_PIXEL2rgb(int **a, int **r, int **g, int **b, int lx, int ly);
PIXEL **img = (PIXEL **)alloc2Darray(sizeof(PIXEL), 100, 100);
int **r = (int **)alloc2Darray(sizeof(int), 100, 100);
image_PIXEL2rgb((int **)img, r, g, b, 100, 100);
void image_rgb2PIXEL(int **r, int **g, int **b, int **a, int lx, int ly);
void rgb2PIXEL_adjust(int **r, int **g, int **b, int **a, int lx, int ly);
rgb2PIXEL_adjust(r, g, b, (int **)img, 100, 100);
void int2PIXEL(int **s, int **d, int lx, int ly);
int2PIXEL(data, (int **)img, 100, 100);
void int2PIXEL_adjust(int **s, int **d, int lx, int ly);
void clamp_and_convert(int **src, PIXEL **dst, int lx, int ly);
void image_set(int v, int **dst, int lx, int ly);
void image_copy(int **a, int **dst, int lx, int ly);
void image_not(int **a, int **dst, int lx, int ly);
void image_and(int **a, int **b, int **dst, int lx, int ly);
void image_or(int **a, int **b, int **dst, int lx, int ly);
void image_xor(int **a, int **b, int **dst, int lx, int ly);
void image_add(int **a, int **b, int **dst, int lx, int ly);
void image_sub(int **a, int **b, int **dst, int lx, int ly);
void image_mul(int **a, int **b, int **dst, int lx, int ly);
void image_div(int **a, int **b, int **dst, int lx, int ly);
void image_add_abs3(int **a, int **b, int **c, int **dst, int lx, int ly);
int **a = (int **)alloc2Darray(sizeof(int), 100, 100);
int **b = (int **)alloc2Darray(sizeof(int), 100, 100);
int **dst = (int **)alloc2Darray(sizeof(int), 100, 100);
image_add(a, b, dst, 100, 100);
void lu_decomposition(double **A, double **L, double **U, int *P, int n);
double **A = (double **)alloc2Darray(sizeof(double), 3, 3);
double **L = (double **)alloc2Darray(sizeof(double), 3, 3);
double **U = (double **)alloc2Darray(sizeof(double), 3, 3);
int *P = (int *)malloc(3 * sizeof(int));
lu_decomposition(A, L, U, P, 3);
void solve_LU(double **L, double **U, int *P, double *b, double *x, int n);
double *b = (double *)malloc(3 * sizeof(double));
double *x = (double *)malloc(3 * sizeof(double));
solve_LU(L, U, P, b, x, 3);
void inverse_matrix(double **A, double **A_inv, int n);
double **A = (double **)alloc2Darray(sizeof(double), 3, 3);
double **A_inv = (double **)alloc2Darray(sizeof(double), 3, 3);
inverse_matrix(A, A_inv, 3);
void multiplication_matrix(double **A, double **B, double **C, int n);
double **C = (double **)alloc2Darray(sizeof(double), 3, 3);
multiplication_matrix(A, B, C, 3);
void dump_array(FILE *fp, char *fmt, char *msg, double **A, int N);
dump_array(stdout, "%f ", "Matrix A:", A, 3);
void HomographyCore(POINTf sp[4], POINTf dp[4], double hkl[3][3]);
POINTf src_pts[4] = {{0,0}, {100,0}, {100,100}, {0,100}};
POINTf dst_pts[4] = {{10,10}, {190,10}, {190,190}, {10,190}};
double hkl[3][3];
HomographyCore(src_pts, dst_pts, hkl);
void DrawLine(PIXEL **canvas, int lx, int ly, int x0, int y0, int x1, int y1, PIXEL pen);
PIXEL **canvas = (PIXEL **)alloc2Darray(sizeof(PIXEL), 100, 100);
PIXEL pen = {255, 0, 0, 0}; // 赤
DrawLine(canvas, 100, 100, 10, 10, 90, 90, pen);
void DrawLineExor(PIXEL **canvas, int lx, int ly, int x0, int y0, int x1, int y1, PIXEL pen);
void DrawPolyline(PIXEL **canvas, int lx, int ly, int num_points, POINTi *points, int close, PIXEL pen);
POINTi pts[4] = {{10,10}, {90,10}, {90,90}, {10,90}};
DrawPolyline(canvas, 100, 100, 4, pts, 1, pen);
void DrawCircle(PIXEL **canvas, int lx, int ly, int cx, int cy, int r, PIXEL pen);
DrawCircle(canvas, 100, 100, 50, 50, 20, pen);
void DrawArc(PIXEL **canvas, int lx, int ly, int cx, int cy, int r, int start_angle, int end_angle, PIXEL pen);
DrawArc(canvas, 100, 100, 50, 50, 20, 0, 90, pen);
void DrawEllipse(PIXEL **canvas, int lx, int ly, int x0, int y0, int x1, int y1, PIXEL pen);
DrawEllipse(canvas, 100, 100, 20, 20, 80, 60, pen);
UnionFind *uf_init(int size);
UnionFind *uf = uf_init(100 * 100);
int uf_find(UnionFind *uf, int x);
void uf_union(UnionFind *uf, int x, int y);
void uf_free(UnionFind *uf);
uf_free(uf);
int uf_count_labels(UnionFind *uf, int *labels, int size);
double get_micro_time();
double start = get_micro_time();
// 処理
double end = get_micro_time();
print_elapsed_time(end - start);
void print_elapsed_time(double microsec);
unsigned int int2PseudoColor(unsigned int v);
unsigned int color = int2PseudoColor(123);
void **alloc2D(void *data, int s, int lx, int ly);
void *data = malloc(100 * 100 * sizeof(int));
int **array = (int **)alloc2D(data, sizeof(int), 100, 100);
void **alloc2Darray(int s, int lx, int ly);
int **array = (int **)alloc2Darray(sizeof(int), 100, 100);
void argumentAnalysis(int argc, char *argv[], char **iname, char **oname);
char *iname, *oname;
argumentAnalysis(argc, argv, &iname, &oname);
void PIXEL_Fitting(PIXEL *s, int lx, int ly);
int image_processing_program(int **s, int **d, int **w, int **t, int **g, int **b, int lx, int ly);
int sobelX[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
convolution(g, w, lx, ly, 3, sobelX);