| template.zip | 76c743b6b19991afcbbbeec7a82ffa92 | 
| template.c | b91514f0ceeb6aae00c4d016952e0eb5 | 
| その他 | 強化版 2025/06/30 version | 
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);
////////////////////////////////////////////////////////////////////////////////
// パブリックドメイン利用の32ビット ハッシュ関数 セキュリティ用途の強度は無い事に注意
//
// Public domain. FNV-1a based on http://www.isthe.com/chongo/tech/comp/fnv/
// Public domain. MurmurHash2 based on https://github.com/aappleby/smhasher, 
// modified with expansion for collision resistance
// And, following code same too.
//
uint32_t fnv1a_hash(const char *str){ if(!str) return 0;
    uint32_t hash = 0x811C9DC5;      // 初期値
    while(*str){
        hash ^= (uint8_t)(*str++);
        hash *= 0x01000193;          // FNV-1aで使用する定数
    }
    return hash;
}