How to use C99 templates.
 C99 テンプレートの使用方法

 
 C99 テンプレートの強化版,Template.c,で提供される機能一覧です。
 
template.zip 76c743b6b19991afcbbbeec7a82ffa92
template.c b91514f0ceeb6aae00c4d016952e0eb5

 
 約1000行のコードなので、AI に一括で読み込ませ、アシストさせることを想定していたのですが、
 現行提供されているバージョンでは難しいようです。  

 前版(約600行)では、一括読み込みと、中々の解析も行えていたので残念ですが、有償バージョン
 なら処理が行えるのかもしれませんが、あくまでコストをかけずに簡便に画像処理の学習ができる
 事を想定していたので、スマートではありませんが、部分的に読み込ませながら、説明させる以外
 なさそうです。
 
 このテンプレートを使って二値画像内の穴の部分を埋める処理は、以下様に記述。I/Oは提供済み
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;
}
 
   TEMPLATES_USE_AS_INCLUDE_FILを設定することで、Template.cに含まれる機能の取り込みも可能。
 
    int image_processing_program(int **s,int **d,int **w,int **t,int **g,int **b,int lx,int ly);
    void argumentAnalysis(int argc, char *argv[], char **iname, char **oname);
    void PIXEL_Fitting( PIXEL *s, int lx, int ly ):
    int main(int argc, char *argv[]):
    を無効化できるので、これらに相当する関数を別ファイルに記述し、
 
   #define TEMPLATES_USE_AS_INCLUDE_FILE
   #include "template.c"
 
   と定義すれば、機能のインポートが可能になる。
   
   コンパイル例:
   gcc -O3 -std=c99 -mavx -W -Wall -Wextra -o Template Template.c -fopenmp -lm
 
 




以下は、提供されたC99テンプレートコード(Template.c)が実装している機能を一覧表形式でまとめたものです。

機能はカテゴリに分け、各機能の概要、関連する主要な関数やマクロ、備考を表に整理しました。
表形式で簡潔かつ見やすく提示します。

カテゴリ
機能
概要
関連関数/マクロ
備考
画像処理
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
柔軟な利用形態

備考
  • 依存: stb_image.h(画像読み込み)、OpenMP(並列化)、標準Cライブラリ。
  • 特徴: 外部ライブラリ依存を最小限に抑え、並列処理対応、柔軟なカスタマイズ性。
  • 拡張性: image_processing_program内でユーザーが自由にアルゴリズムを実装可能。
  • 制限: 一部の機能(例: ラベリングのオプション)はコメントアウトされており、未使用。



C99テンプレートコード(Template.c)に含まれる全関数のインターフェースと使用方法
を以下に詳細に説明します。
関数はカテゴリ別に整理し、各関数の目的、引数、戻り値、使用方法、注意点を明確に記載
します。 マクロやデータ構造も必要に応じて参照しますが、関数のインターフェースに
焦点を当て、簡潔かつ包括的に説明します。
コードが長大なため、説明は実用的な情報を優先し、表形式でなく記述形式で提供します。


1. 画像処理関連関数
1.1. saveDataAsBMP32
  • 目的: 32ビットBMP形式で画像データをファイルに保存する。
  • インターフェース:

      c  
    int saveDataAsBMP32(char *fname, void *b, int lx, int ly);
  • 引数:
    • fname: 出力ファイル名(文字列)。
    • b: ピクセルデータのポインタ(PIXEL構造体の配列として扱われる)。
    • lx: 画像の幅(ピクセル数)。
    • ly: 画像の高さ(ピクセル数、負値で上下反転)。
  • 戻り値:
    • 0: 成功。
    • -1: ファイル作成、ヘッダ書き込み、またはデータ書き込みに失敗。
  • 使用方法:
    • ピクセルデータ(PIXEL型)を準備し、ファイル名、幅、高さを指定して呼び出す。
    • マクロsaveArray2bmp32(name, a, w, h)を使用すると、aの先頭アドレスを自動的に渡せる。
    • 例:

        c  
      PIXEL **img = (PIXEL **)alloc2Darray(sizeof(PIXEL), 100, 100);
      // imgにデータをセット
      saveArray2bmp32("output.bmp", img, 100, 100);
  • 注意点:
    • bPIXEL型の連続メモリである必要がある。
    • ファイルオープンエラーや書き込みエラー時にエラーメッセージをstderrに出力。
    • メモリ解放は呼び出し側で管理。
1.2. fourierTransform
  • 目的: 2次元フーリエ変換(DFT/FFT、IDFT/IFFT)を実行する。
  • インターフェース:

      c  
    int fourierTransform(COMPLEX **d, int lx, int ly, int flag);
  • 引数:
    • d: 複素数データ(COMPLEX型)の2次元配列(入力および出力)。
    • lx: 横方向のデータサイズ。
    • ly: 縦方向のデータサイズ。
    • flag: DFT(順変換)またはIDFT(逆変換)。
  • 戻り値:
    • 0: 成功。
    • 1: メモリ割り当て失敗。
  • 使用方法:
    • 複素数データをCOMPLEX **dに格納し、サイズと変換方向を指定。
    • 2のべき乗サイズの場合、FFTを使用。それ以外はDFT。
    • 例:

        c  
      COMPLEX **data = (COMPLEX **)alloc2Darray(sizeof(COMPLEX), 128, 128);
      // dataに値をセット
      fourierTransform(data, 128, 128, DFT);
  • 注意点:
    • rotorバッファの共有による競合条件に注意(並列処理時)。
    • ft_size_checkで2のべき乗をチェックするが、ゼロや負の入力は未検証。
    • メモリ解放は呼び出し側で管理。
1.3. PowerSpectrum
  • 目的: フーリエ変換結果からパワースペクトルを計算し、グレースケール画像として保存。
  • インターフェース:

      c  
    void PowerSpectrum(char *fname, COMPLEX **u, PIXEL **a, int lx, int ly);
  • 引数:
    • fname: 出力BMPファイル名(NULLの場合、保存しない)。
    • u: 複素数データ(COMPLEX型)の2次元配列。
    • a: 出力ピクセルデータ(PIXEL型)の2次元配列。
    • lx: 画像の幅。
    • ly: 画像の高さ。
  • 戻り値: なし。
  • 使用方法:
    • フーリエ変換後のデータをuに渡し、結果をaに格納。必要ならfnameで保存。
    • 例:

        c  
      COMPLEX **freq = (COMPLEX **)alloc2Darray(sizeof(COMPLEX), 128, 128);
      PIXEL **img = (PIXEL **)alloc2Darray(sizeof(PIXEL), 128, 128);
      PowerSpectrum("spectrum.bmp", freq, img, 128, 128);
  • 注意点:
    • パワースペクトルは対数スケールで正規化される。
    • max - minが非常に小さい場合、除算エラーを防ぐためINF_ZEROを使用。
    • メモリ管理は呼び出し側で。
1.4. HomographyTrans
  • 目的: ホモグラフィ変換を適用して画像を変換する。
  • インターフェース:

      c  
    void HomographyTrans(PIXEL **c, int lx, int ly, PIXEL **s, int slx, int sly, double inv[3][3]);
  • 引数:
    • c: 出力画像(PIXEL型)の2次元配列。
    • lx, ly: 出力画像の幅と高さ。
    • s: 入力画像(PIXEL型)の2次元配列。
    • slx, sly: 入力画像の幅と高さ。
    • inv: ホモグラフィ変換の逆行列(3x3)。
  • 戻り値: なし。
  • 使用方法:
    • ホモグラフィ行列の逆行列を計算済みの状態で、入力画像を変換して出力。
    • 例:

        c  
      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);
  • 注意点:
    • 境界外は白色({255,255,255,0})で埋める。
    • 並列化対応(#pragma omp parallel for)。
1.5. HomographyTransMask
  • 目的: マスクを適用したホモグラフィ変換。
  • インターフェース:

      c  
    void HomographyTransMask(PIXEL **c, int lx, int ly, PIXEL **s, int slx, int sly, int **mask, double inv[3][3]);
  • 引数:
    • mask: マスクデータ(int型、0以外でマスク適用)。
    • その他はHomographyTransと同じ。
  • 戻り値: なし。
  • 使用方法:
    • マスクを使用して、特定領域を除外したホモグラフィ変換。
    • 例:

        c  
      int **mask = (int **)alloc2Darray(sizeof(int), 100, 100);
      // maskに値をセット
      HomographyTransMask(dst, 200, 200, src, 100, 100, mask, inv);
  • 注意点:
    • マスクが0以外のピクセルはスキップされる。
    • 並列化対応。
1.6. Homography
  • 目的: 4点対応からホモグラフィ変換を計算し、画像変換を実行。
  • インターフェース:

      c  
    void Homography(PIXEL **s, int slx, int sly, int **mask, POINTf sp[4], PIXEL **d, int lx, int ly, POINTf dp[4]);
  • 引数:
    • s, slx, sly: 入力画像とそのサイズ。
    • mask: マスクデータ(NULL可)。
    • sp: 入力画像の4点座標(POINTf型)。
    • d, lx, ly: 出力画像とそのサイズ。
    • dp: 出力画像の4点座標(POINTf型)。
  • 戻り値: なし。
  • 使用方法:
    • 4点対応を指定し、ホモグラフィ変換を適用。
    • 例:

        c  
      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);
  • 注意点:
    • 内部でHomographyCoreinverse_matrixを呼び出す。
    • マスクがNULLの場合、HomographyTransを、それ以外の場合はHomographyTransMaskを使用。
1.7. labeling
  • 目的: 4/8連結成分ラベリングを実行。
  • インターフェース:

      c  
    int labeling(int **b, int **labels, int lx, int ly, int connectivity);
  • 引数:
    • b: 入力バイナリ画像(0が背景、0以外が前景)。
    • labels: ラベルデータ(出力、初期値0)。
    • lx, ly: 画像の幅と高さ。
    • connectivity: 連結性(4または8)。
  • 戻り値:
    • ラベル数(成功時)。
    • -1: 無効な引数またはメモリ割り当て失敗。
  • 使用方法:
    • バイナリ画像を準備し、ラベル配列を初期化して呼び出す。
    • 例:

        c  
      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);
  • 注意点:
    • Union-Findアルゴリズムを使用し、2パス処理。
    • 第1パスは逐次処理、第2パスは並列化。
    • メモリ解放は呼び出し側で。
1.8. convolution
  • 目的: 整数型カーネルで2次元畳み込みを計算(ゼロパディング)。
  • インターフェース:

      c  
    void convolution(int **s, int **d, int lx, int ly, int n, int kernel[n][n]);
  • 引数:
    • s: 入力画像(int型)。
    • d: 出力画像(int型)。
    • lx, ly: 画像の幅と高さ。
    • n: カーネルのサイズ(正方形)。
    • kernel: カーネルデータ(n x n)。
  • 戻り値: なし。
  • 使用方法:
    • 例(Sobelフィルタ):

        c  
      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);
  • 注意点:
    • 境界外はゼロパディング。
    • 並列化対応。
1.9. convolution_float
  • 目的: 浮動小数点カーネルで2次元畳み込みを計算。
  • インターフェース:

      c  
    void convolution_float(float **s, float **d, int lx, int ly, int n, float kernel[n][n]);
  • 引数: convolutionと同様だが、データ型がfloat
  • 戻り値: なし。
  • 使用方法: convolutionと同様。
  • 注意点:
    • 整数型と比べて高精度だが、計算コストが高い。
1.10. image_PIXEL2rgb
  • 目的: PIXEL画像からRGBチャンネルを分離。
  • インターフェース:

      c  
    void image_PIXEL2rgb(int **a, int **r, int **g, int **b, int lx, int ly);
  • 引数:
    • a: 入力画像(PIXEL型)。
    • r, g, b: 出力チャンネル(int型)。
    • lx, ly: 画像の幅と高さ。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      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);
  • 注意点:
    • aPIXEL型としてキャストされる。
1.11. image_rgb2PIXEL
  • 目的: RGBチャンネルからPIXEL画像を生成(クランプあり)。
  • インターフェース:

      c  
    void image_rgb2PIXEL(int **r, int **g, int **b, int **a, int lx, int ly);
  • 引数:
    • r, g, b: 入力チャンネル(int型)。
    • a: 出力画像(PIXEL型)。
    • lx, ly: 画像の幅と高さ。
  • 戻り値: なし。
  • 使用方法: image_PIXEL2rgbの逆処理。
  • 注意点:
    • 値は0~255にクランプされる。
1.12. rgb2PIXEL_adjust
  • 目的: RGBチャンネルを正規化してPIXEL画像を生成。
  • インターフェース:

      c  
    void rgb2PIXEL_adjust(int **r, int **g, int **b, int **a, int lx, int ly);
  • 引数: image_rgb2PIXELと同様。
  • 戻り値: なし。
  • 使用方法:
    • 各チャンネルの最小・最大値を計算し、0~255にスケーリング。
    • 例:

        c  
      rgb2PIXEL_adjust(r, g, b, (int **)img, 100, 100);
  • 注意点:
    • 最小値と最大値が同じ場合、除算を回避。
1.13. int2PIXEL
  • 目的: 整数データをグレースケールPIXEL画像に変換(クランプあり)。
  • インターフェース:

      c  
    void int2PIXEL(int **s, int **d, int lx, int ly);
  • 引数:
    • s: 入力データ(int型)。
    • d: 出力画像(PIXEL型)。
    • lx, ly: 画像の幅と高さ。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      int2PIXEL(data, (int **)img, 100, 100);
  • 注意点:
    • 値は0~255にクランプ。
1.14. int2PIXEL_adjust
  • 目的: 整数データを正規化してグレースケールPIXEL画像に変換。
  • インターフェース:

      c  
    void int2PIXEL_adjust(int **s, int **d, int lx, int ly);
  • 引数: int2PIXELと同様。
  • 戻り値: なし。
  • 使用方法: int2PIXELと同様だが、正規化を行う。
  • 注意点:
    • 最小値と最大値が同じ場合、127を基準に調整。
1.15. clamp_and_convert
  • 目的: 整数データをクランプしてグレースケールPIXEL画像に変換。
  • インターフェース:

      c  
    void clamp_and_convert(int **src, PIXEL **dst, int lx, int ly);
  • 引数:
    • src: 入力データ(int型)。
    • dst: 出力画像(PIXEL型)。
    • lx, ly: 画像の幅と高さ。
  • 戻り値: なし。
  • 使用方法: int2PIXELと同様。
  • 注意点:
    • 機能はint2PIXELとほぼ同じ。
1.16. 基本画像演算関数
以下の関数はピクセル単位の演算を提供:
  • インターフェース(共通):

      c  
    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);
  • 引数:
    • v: 定数値(image_setのみ)。
    • a, b, c: 入力データ(int型)。
    • dst: 出力データ(int型)。
    • lx, ly: 画像の幅と高さ。
  • 戻り値: なし。
  • 使用方法:
    • 例(加算):

        c  
      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);
  • 注意点:
    • image_divはゼロ除算を回避(b[y][x] != 0)。
    • 並列化対応(PROCESS_ALL_PIXELSマクロ使用)。
2. 行列演算関連関数
2.1. lu_decomposition
  • 目的: ピボット選択付きLU分解を実行。
  • インターフェース:

      c  
    void lu_decomposition(double **A, double **L, double **U, int *P, int n);
  • 引数:
    • A: 入力行列(n x n)。
    • L, U: 出力の下三角行列と上三角行列。
    • P: ピボット交換用の配列。
    • n: 行列のサイズ。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      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);
  • 注意点:
    • メモリ割り当ては呼び出し側で管理。
    • ピボット交換で数値安定性を向上。
2.2. solve_LU
  • 目的: LU分解を用いて連立方程式を解く。
  • インターフェース:

      c  
    void solve_LU(double **L, double **U, int *P, double *b, double *x, int n);
  • 引数:
    • L, U, P: LU分解の結果(lu_decompositionから)。
    • b: 右辺ベクトル。
    • x: 解ベクトル(出力)。
    • n: 行列のサイズ。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      double *b = (double *)malloc(3 * sizeof(double));
      double *x = (double *)malloc(3 * sizeof(double));
      solve_LU(L, U, P, b, x, 3);
  • 注意点:
    • メモリ割り当てエラー時にexit(1)を呼び出す。
2.3. inverse_matrix
  • 目的: 行列の逆行列を計算。
  • インターフェース:

      c  
    void inverse_matrix(double **A, double **A_inv, int n);
  • 引数:
    • A: 入力行列(n x n)。
    • A_inv: 逆行列(出力)。
    • n: 行列のサイズ。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      double **A = (double **)alloc2Darray(sizeof(double), 3, 3);
      double **A_inv = (double **)alloc2Darray(sizeof(double), 3, 3);
      inverse_matrix(A, A_inv, 3);
  • 注意点:
    • 内部でlu_decompositionsolve_LUを使用。
    • 並列化対応。
2.4. multiplication_matrix
  • 目的: 2つの行列の積を計算。
  • インターフェース:

      c  
    void multiplication_matrix(double **A, double **B, double **C, int n);
  • 引数:
    • A, B: 入力行列(n x n)。
    • C: 結果行列(出力)。
    • n: 行列のサイズ。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      double **C = (double **)alloc2Darray(sizeof(double), 3, 3);
      multiplication_matrix(A, B, C, 3);
  • 注意点:
    • 並列化対応。
2.5. dump_array
  • 目的: 行列データをフォーマットして出力。
  • インターフェース:

      c  
    void dump_array(FILE *fp, char *fmt, char *msg, double **A, int N);
  • 引数:
    • fp: 出力先ファイルポインタ(stdout可)。
    • fmt: フォーマット文字列(例: "%f ")。
    • msg: ヘッダメッセージ(NULL可)。
    • A: 出力行列。
    • N: 行列のサイズ。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      dump_array(stdout, "%f ", "Matrix A:", A, 3);
  • 注意点:
    • デバッグ用。
2.6. HomographyCore
  • 目的: 4点対応からホモグラフィ行列を計算。
  • インターフェース:

      c  
    void HomographyCore(POINTf sp[4], POINTf dp[4], double hkl[3][3]);
  • 引数:
    • sp: 入力画像の4点座標。
    • dp: 出力画像の4点座標。
    • hkl: ホモグラフィ行列(出力、3x3)。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      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);
  • 注意点:
    • 内部でinverse_matrixを使用。
3. 描画関連関数
3.1. DrawLine
  • 目的: 直線を描画(Bresenhamアルゴリズム)。
  • インターフェース:

      c  
    void DrawLine(PIXEL **canvas, int lx, int ly, int x0, int y0, int x1, int y1, PIXEL pen);
  • 引数:
    • canvas: 描画対象画像(PIXEL型)。
    • lx, ly: 画像の幅と高さ。
    • x0, y0, x1, y1: 直線の始点と終点。
    • pen: 描画色(PIXEL型)。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      PIXEL **canvas = (PIXEL **)alloc2Darray(sizeof(PIXEL), 100, 100);
      PIXEL pen = {255, 0, 0, 0}; // 赤
      DrawLine(canvas, 100, 100, 10, 10, 90, 90, pen);
  • 注意点:
    • 境界チェックあり。
3.2. DrawLineExor
  • 目的: XORモードで直線を描画。
  • インターフェース:

      c  
    void DrawLineExor(PIXEL **canvas, int lx, int ly, int x0, int y0, int x1, int y1, PIXEL pen);
  • 引数: DrawLineと同様。
  • 戻り値: なし。
  • 使用方法: DrawLineと同様だが、ピクセル値をXOR演算。
  • 注意点:
    • 重ね書きで元の値を復元可能。
3.3. DrawPolyline
  • 目的: 複数点の線分(ポリライン)を描画。
  • インターフェース:

      c  
    void DrawPolyline(PIXEL **canvas, int lx, int ly, int num_points, POINTi *points, int close, PIXEL pen);
  • 引数:
    • num_points: 点の数。
    • points: 点の配列(POINTi型)。
    • close: 閉形状にするか(0/1)。
    • その他はDrawLineと同様。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      POINTi pts[4] = {{10,10}, {90,10}, {90,90}, {10,90}};
      DrawPolyline(canvas, 100, 100, 4, pts, 1, pen);
  • 注意点:
    • num_points < 2で何もしない。
3.4. DrawCircle
  • 目的: 円を描画(Bresenhamアルゴリズム)。
  • インターフェース:

      c  
    void DrawCircle(PIXEL **canvas, int lx, int ly, int cx, int cy, int r, PIXEL pen);
  • 引数:
    • cx, cy: 円の中心。
    • r: 半径。
    • その他はDrawLineと同様。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      DrawCircle(canvas, 100, 100, 50, 50, 20, pen);
  • 注意点:
    • 8方向の対称性を利用。
3.5. DrawArc
  • 目的: 指定角度範囲の円弧を描画。
  • インターフェース:

      c  
    void DrawArc(PIXEL **canvas, int lx, int ly, int cx, int cy, int r, int start_angle, int end_angle, PIXEL pen);
  • 引数:
    • start_angle, end_angle: 開始・終了角度(度)。
    • その他はDrawCircleと同様。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      DrawArc(canvas, 100, 100, 50, 50, 20, 0, 90, pen);
  • 注意点:
    • 角度は0~360度に正規化。
    • ラップアラウンド(start_angle > end_angle)対応。
3.6. DrawEllipse
  • 目的: 楕円を描画。
  • インターフェース:

      c  
    void DrawEllipse(PIXEL **canvas, int lx, int ly, int x0, int y0, int x1, int y1, PIXEL pen);
  • 引数:
    • x0, y0, x1, y1: 楕円の対角点。
    • その他はDrawLineと同様。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      DrawEllipse(canvas, 100, 100, 20, 20, 80, 60, pen);
  • 注意点:
    • 0.1度ステップで近似描画。
    • 無効なサイズ(a <= 0またはb <= 0)で何もしない。
4. Union-Find関連関数
4.1. uf_init
  • 目的: Union-Findデータ構造を初期化。
  • インターフェース:

      c  
    UnionFind *uf_init(int size);
  • 引数:
    • size: ノード数。
  • 戻り値:
    • UnionFind構造体のポインタ(失敗時はNULL)。
  • 使用方法:
    • 例:

        c  
      UnionFind *uf = uf_init(100 * 100);
  • 注意点:
    • メモリ割り当て失敗時にNULLを返す。
4.2. uf_find
  • 目的: ノードのルートを検索(経路圧縮あり)。
  • インターフェース:

      c  
    int uf_find(UnionFind *uf, int x);
  • 引数:
    • uf: Union-Find構造体。
    • x: ノード番号。
  • 戻り値: ルートノードの番号。
  • 使用方法:
    • labeling内で使用。
  • 注意点:
    • 経路圧縮で効率化。
4.3. uf_union
  • 目的: 2つのノードを結合(ランク付き)。
  • インターフェース:

      c  
    void uf_union(UnionFind *uf, int x, int y);
  • 引数:
    • uf: Union-Find構造体。
    • x, y: 結合するノード番号。
  • 戻り値: なし。
  • 使用方法:
    • labeling内で使用。
  • 注意点:
    • ランクを使用して木の高さを最適化。
4.4. uf_free
  • 目的: Union-Find構造体のメモリを解放。
  • インターフェース:

      c  
    void uf_free(UnionFind *uf);
  • 引数:
    • uf: Union-Find構造体。
  • 戻り値: なし。
  • 使用方法:
    • 例:

        c  
      uf_free(uf);
  • 注意点:
    • ufNULLでも安全。
4.5. uf_count_labels
  • 目的: ラベル数をカウント。
  • インターフェース:

      c  
    int uf_count_labels(UnionFind *uf, int *labels, int size);
  • 引数:
    • uf: Union-Find構造体。
    • labels: ラベルデータ。
    • size: データサイズ。
  • 戻り値: ユニークなラベル数。
  • 使用方法:
    • labeling内で使用。
  • 注意点:
    • 内部で一時バッファを使用。
5. 補助関数
5.1. get_micro_time
  • 目的: マイクロ秒単位の現在時刻を取得。
  • インターフェース:

      c  
    double get_micro_time();
  • 引数: なし。
  • 戻り値: マイクロ秒単位の時刻。
  • 使用方法:
    • 例:

        c  
      double start = get_micro_time();
      // 処理
      double end = get_micro_time();
      print_elapsed_time(end - start);
  • 注意点:
    • Windows(QueryPerformanceCounter)とUnix(gettimeofday)で異なる実装。
    • gettimeofdayは非推奨(clock_gettime推奨)。
5.2. print_elapsed_time
  • 目的: 経過時間を適切な単位(秒、ミリ秒、マイクロ秒)で表示。
  • インターフェース:

      c  
    void print_elapsed_time(double microsec);
  • 引数:
    • microsec: 経過時間(マイクロ秒)。
  • 戻り値: なし。
  • 使用方法:
    • 上記例参照。
  • 注意点:
    • 自動的に適切な単位を選択。
5.3. int2PseudoColor
  • 目的: 整数値を疑似カラー(RGB)に変換。
  • インターフェース:

      c  
    unsigned int int2PseudoColor(unsigned int v);
  • 引数:
    • v: 入力値。
  • 戻り値: RGB値(uint32_t形式)。
  • 使用方法:
    • 例:

        c  
      unsigned int color = int2PseudoColor(123);
  • 注意点:
    • ビット単位でRGBを生成。
5.4. alloc2D
  • 目的: 既存メモリブロックに2次元インデックスを作成。
  • インターフェース:

      c  
    void **alloc2D(void *data, int s, int lx, int ly);
  • 引数:
    • data: 既存のメモリブロック。
    • s: 要素のサイズ。
    • lx, ly: 幅と高さ。
  • 戻り値: 2次元ポインタ(失敗時はNULL)。
  • 使用方法:
    • 例:

        c  
      void *data = malloc(100 * 100 * sizeof(int));
      int **array = (int **)alloc2D(data, sizeof(int), 100, 100);
  • 注意点:
    • dataは初期化済みである必要がある。
5.5. alloc2Darray
  • 目的: 連続メモリで2次元配列を割り当て。
  • インターフェース:

      c  
    void **alloc2Darray(int s, int lx, int ly);
  • 引数:
    • s: 要素のサイズ。
    • lx, ly: 幅と高さ。
  • 戻り値: 2次元ポインタ(失敗時はNULL)。
  • 使用方法:
    • 例:

        c  
      int **array = (int **)alloc2Darray(sizeof(int), 100, 100);
  • 注意点:
    • メモリはゼロ初期化される。
5.6. argumentAnalysis
  • 目的: コマンドライン引数を解析。
  • インターフェース:

      c  
    void argumentAnalysis(int argc, char *argv[], char **iname, char **oname);
  • 引数:
    • argc, argv: コマンドライン引数。
    • iname, oname: 入力/出力ファイル名(出力)。
  • 戻り値: なし(エラー時はexit)。
  • 使用方法:
    • 例:

        c  
      char *iname, *oname;
      argumentAnalysis(argc, argv, &iname, &oname);
  • 注意点:
    • オプション: -v(詳細)、-V(詳細+)、-n(ネガポジ反転)、-a(自動正規化)、-t(スレッド数)、-h(ヘルプ)。
    • コメントアウトされたオプション(-c, -k, -s, -b)は未使用。
5.7. PIXEL_Fitting
  • 目的: ピクセルデータの色順序を変更(BGRRGB)および上下反転。
  • インターフェース:

      c  
    void PIXEL_Fitting(PIXEL *s, int lx, int ly);
  • 引数:
    • s: ピクセルデータ(PIXEL型)。
    • lx, ly: 幅と高さ。
  • 戻り値: なし。
  • 使用方法:
    • main内でstbi_load後のデータ処理に使用。
  • 注意点:
    • 内部でv2Dpマクロを使用。
5.8. image_processing_program
  • 目的: ユーザーがカスタム画像処理を実装するためのエントリポイント。
  • インターフェース:

      c  
    int image_processing_program(int **s, int **d, int **w, int **t, int **g, int **b, int lx, int ly);
  • 引数:
    • s: 入力画像(PIXEL型)。
    • d: 出力画像(int型またはPIXEL型)。
    • w, t, g, b: 作業用バッファ(int型、tはグレースケールPIXEL)。
    • lx, ly: 画像の幅と高さ。
  • 戻り値:
    • 0: 成功。
    • その他: エラー。
  • 使用方法:
    • ユーザーが処理を追加(例: Sobelフィルタ、ラベリング)。
    • 例:

        c  
      int sobelX[3][3] = {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};
      convolution(g, w, lx, ly, 3, sobelX);
  • 注意点:
    • 作業バッファは呼び出し側で確保済み。
    • save_without_conversionで出力形式を制御。

まとめと注意点
  • 共通の注意:
    • メモリ管理は呼び出し側で責任を持つ(alloc2Darrayの解放など)。
    • OpenMP並列化を使用する関数(fourierTransform, convolutionなど)は、スレッドセーフ性を確認する必要がある。
    • エラー処理は部分的に不十分(例: メモリ割り当て失敗時の解放漏れ)。 AIの誤認、精度はこの程度
  • インターフェースの特徴:
    • 関数は型安全性と柔軟性を考慮し、ポインタベースの入出力。
    • マクロ(v2D, PROCESS_ALL_PIXELSなど)でコードを簡略化。
  • 使用時の推奨:
    • メモリ割り当てエラーを常にチェック。
    • 大きなデータサイズでは、並列化の効果とメモリ使用量を考慮。
特定の関数の詳細な使用例やコードサンプルが必要な場合、または特定の機能に焦点を当てたい場合は、ぜひご指定ください。