92 4 画像の圧縮符号化法 for ( j = 0 ; j く DIMENSION; j + + ) { sum[j] = 0.0 ; sum number = 0.0 ; for ( y = 0 ; y く y—block; Y + + ) { for ( x = 0 ; x く x block; x + + ) { if ( clu ster [y][x] = sum number ニ sum_number 十 1.0 ; for ( j = 0 ; j く DIMENSION; j + + ) sum[j] = sum[j] + vector[y][x] 阯 for ( j = 0 ; j く DIMENSION; j + + ) { main—vector[i][j] = (unsigned char) ( sum[j] / sum—number ) ; だクラスタ中心が移動したかどうかのチェック * / finish = 1 ; for ( i = 0 ; i く K number; i + + ) { difference = 0.0 ; for ( j = 0 ; j < DIMENSION; j + + ) { difference = difference + abs( init-main-vector[i][j] - main-vector[i][j]); if ( difference > MIN—DIFFERENCE ) finish = 0 ; if ( finish = = 1 ) { / ☆処理終了 * / だ各プロックを代表べクトルに置き換える * / y—size2 = y—sizel; X Size2 = X sizel; for ( y = 0 ; y く y—block; y + + ) { for ( x = 0 ; x く x block; x + + ) { xs = BLOCK_SIZE * x; ys = BLOCK_SIZE * y; for ( i = 0 ; i く BLOCK SIZE; i + + ) { for (j = 0 ; j く BLOCK-SIZE; j + + ) { image2[ ys + i][ xs + j] = main—vector[ cluster[y][x]] [i*BLOCK_SIZE + j] ;
4 画像の圧縮符号化法 scanf("%d" &K number); } while ( K—number く 8 Ⅱ K_number > MAX CLUSTERS ) ; だ仮代表べクトルの設定 * / for ( i = 0 ; i く K—number; i + + ) { x = random int( x block ) ; y = random—int( y—block ) ; for ( j = 0 ; j く DIMENSION; j + + ) { main-vector[i][j] = vector[y][x] 阯 / * K - 平均法によってべクトルのクラスタリングを行う * / finish = 0 ; counter = 0 ; while ( ! finish ) { counter 十十 ; printf("%d 回目のクラスタリング中です . ¥Ⅱ " , counter ) ; / * クラスタの初期代表点への代人 * / for ( i = 0 ; i < K number; i + + ) { for ( j = 0 ; j < DIMENSION; j + + ) init_main—vector[i] = main_vector[i] [j] ; だ各プロックの所属クラスタ番号の初期化 * / for ( y = 0 ; y く y_block; y + + ) for ( x = 0 ; x < x block; x + + ) cluster[y][x] = だ各点の所属クラスタを決定する * / for ( y = 0 ; y < y_block; y + + ) { for ( x = 0 ; x く x_block; x + + ) { だ各クラスタ代表点との距離を求める * / min—distance = 255 * 255 * DIMENSION; for ( i = 0 ; i く K number; i + + ) { distance = calc distance( y, x, i ) ; if ( distance < min distance){ min distance = distance; mm_num = 1 ; for ( i = 0 ; i く K_number; i + + ) { だ各クラスタの代表点を修正する * / cluster[y][x] = min_num; だ [y][x]7' ロックをクラスタ No. min_num ー、属させる * / 91
24 2 画像のフィルタリング return 0 ; save—lmage—data( ) ; だ image2 を保存する * / spacial—filtering( ) ; / * 空間フィルタリングして image2 へ * / load—image—data( ) ; だ画像を読み込んで imagel へ * / main( ) image2[y][x] = (unsigned char)pixel_value; ( max - min ) ま ( pixel—value - min ) ; pixel—value = MAX BRIGHTNESS / pixel—value = pixel—value / div const; weight[i + 1 川 + 1 い imagel[y + i][x + j]; pixel_value = pixel value 十 for ( j = -1 ; j < 2 ; j 十十 ) for ( i = - 1 ; i く 2 ; i 十十 ) pixel—value = 0.0 ; for()= 1 ; x<x_sizel - 1 ; x + + ) { for()= 1 ; y<y_sizel - 1 ; y 十 + ) { / * 処理後の値を線形変換してから image2 に代入 * / image2[y][xI = 0 ; for ( x = 0 ; x く x_sizeX x 十十 ) for ( y = 0 ; y < y_size2; y + + ) x_size2 = x_sizel; y_size2 = y_sizel; / * image2[y][x] の初期化 ( 外郭の画素のため ) if ( (int)(max - min) = = 0 ) exit(l); if ( pixel_value > max ) max = pixel_value; if ( pixel_value く min ) min = pixel_value; pixel—value = pixel—value / div const; weight[i + 1 川 + 1 ] * imagel[y + i][x + 引 ; pixel—value = pixel—value 十 for ( j = -1 ; j く 2 ; j + 十 ) for ( i = - 1 ; i く 2 ; i 十十 ) pixel—value = 0.0 ; for ( x = 1 ; x < x sizel - 1 ; x + + ) { for()= 1 ; y<y—sizel - 1 ; y 十 + ) { max = (double)INT MIN;
3 2 値画像処理 for ( y = 0 ; y く y—size2; y + + ) for ()= 0 ; x<x_size2; x + + ) image2 [y][x] = imagel [y][x] ; printf(" 2 値画像の 8 近傍収縮処理を行います . vn"); printf(" 収縮処理を行う回数 = " ) ; scanf("%d" &repetition); for ( i = 0 ; i く repetition; i 十十 ) { for()= 0 ; y<y—sizel; y + + ) { for ()= 0 ; x<x_sizel; x + + ) { 実行結果 . return 0 ; save—image—data( ) ; / ☆ image2 を保存する * / erosion( ) ; だ 8 近傍収縮処理して image2 へ * / load—image—data( ) ; だ画像を読み込んで imagel へ * / main( ) imagel[y][x] = image2 [y][x] ; for ( x = 0 ; x く x—size2; x + + ) for ( y = 0 ; y く y_size2; y + + ) if ( counter > 0 ) image2[y][x] = 0 ; counter 十十 ; im a ge I[P-Y][P-X] = p—y > 0 & & p—y く y—sizel & & if( p—x > 0 & & p—x く x—sizel & & p—y = Y 十 m; p_x = X 十 n; for ( n = -1 ; n < 2 ; n + + ) { for ( m = -1 ; m < 2 ; m + + ) { counter = 0 ; if ( imagel[y][x] = = MAX BRIGHTNESS ) { 51 図 3.4 ( a ) の 2 値画像 ( 図 3.2 ( b ) と同じ画像 ) に対して , 5 回の 8 近傍収縮 処理を施した結果を同図 ( b ) に示す . 8 近傍収縮処理によって , 図形が内側に
56 3 2 値画像処理 for()= 0 ; y<y—sizel;y + + ){ for ( x = 0 ; x く x_sizel; x 十 + ) { だ ( x , y ) を含む 9 近傍にデータを代入する * / for ( i = 0 ; i < 9 ; i + + ) { px = x + offset[i][0]; py = y + offset[i][l]; if( px > = 0 & & px く x—sizel & & py > = 0 & & py く y—sizel ) if ( image2 [py][px] = = MAX BRIGHTNESS ) for ( i = 0 ; i く 6 ; i + + ) condition[i] = 0 ; else if ( image2 [py][px] = = GRAY)b[i] = だ条件 2 : 境界点である * / if ( b[O] = = 1 ) condition[O] = 1 ; / * 条件 1 : 図形画素である * / sum = 0 ; for ( i = 0 ; i < 4 ; i + + ) -1 ) sum 十十 ; for ( i = 1 ; i く = 8 ; i + + ) sum = 0 ; だ条件 6 : 線幅 2 の線分の片側だけを削除する * / if ( func nc8( b ) = = 1 ) condition[4] = 1 ; だ条件 5 : 連結性を保存する * / if ( sum > = 1 ) condition[3] = 1 ; = 1 ) sum + 十 ; if(b[i] = for ( i = 1 ; i く = 8 ; i + + ) sum = 0 ; だ条件 4 : 孤立点を保存する * / if ( sum > = 2 ) condition[2] sum = sum + abs( b[i]); for ( i = 1 ; i く = 8 ; i + + ) sum = 0 ; だ条件 3 : 端点を除去しない * / if ( sum > = 1 ) condition[ll sum = sum + 1 - abs()[ n odd[i] ]);
1 画像の入力・補正・出力 だ画像の濃度ヒストグラムの画像を作るプログラム histgram. c*/ #include<stdio. h> #include<stdlib. h> #include<limits. h> #include"mypgm. h" #define IMAGESIZE 256 だ = GRAYLEVEL * / void make_histogram—image( ) だ原画像 imagel のヒストグラムを作り画像として image2 に代入 * / long int histogram[GRAYLEVEL]; だヒストグラム用配列 * / だヒストグラム画像を image2 に代入響 printf(" 頻度の最大値 = %dVn", max_frequency); max—frequency = histogram[i] ; if ( histogram[i] > max_frequency ) for ( i = 0 ; i < GRAYLEVEL; i + + ) max—frequency = INT—MIN; だ頻度の最大値を求める * / histogram[ imagel [y][x]] + + ; for ( x = 0 ; x < x sizel; x 十十 ) for ()= 0 ; y<y_sizel; y 十十 ) printf(" 今 , 原画像のヒストグラムを求めています . vn"); histogram[ i ] = 0 ; for ( i = 0 ; i < GRAYLEVEL; i + + ) だ原画像のヒストグラムを求める * / intdata;/* 頻度を表すグラフの長さ * / inti,j, x, y;/* 制御変数☆ / long int max—frequency; だ頻度の最大値 * / main( ) image2[IMAGESIZE-1-j][i] = MAX BRIGHTNESS; for ( j = 0 ; j く data; j + + ) (double)max—frequency * (double)histogram[i]); data = (int)( MAX BRIGHTNESS / for ( i = 0 ; i く GRAYLEVEL; i + + ) { image2[y][x] = 0 ; for ( x = 0 ; x < x_sizeX x + + ) for ( y = 0 ; y く y_size2; y + 十 ) y—size2 = IMAGESIZE; x size2 = IMAGESIZE; 5
7 動画像処理 intx, y;/* 制御変数 * / intvx,vy,step;/* 速度べクトル , べクトルを求める点の間隔 * / printf("frame No. 1 を読み込みます . Vn"); / * imagel - - > image2 copy—image1_t0—image2( ) ; / * frame No. 2 ー > imagel ☆ / load—image—data( ) ; printf("frame NO. 2 を読み込みます . yn"); printf("= = 動きべクトルの検出 = main( ) draw-vector( x, y, x-vctr[y][x] , y-vctr[y][x]); if ( ( y % step ) = = 0 & & ( x % step ) = for ( x = 0 ; x く x—size2; x + + ) for ( y = 0 ; y く y_size2; y 十 + ) image2[y][x] = 0 ; for (x = 0 ; x く x—sizeX x 十 + ) for ( y = 0 ; y < y—sizeX y + + ) だ計測結果を画像にする * / x vctr[y][x] = vx; y-vctr [y][x] = vy ; calc_motion_vector( x, y, &vx, &vy ) ; if ( ( x % step ) = = 0 ) { for(x=O; x<x_sizel; x + + ) { if ( ( y % step ) = printf("line %dYn",y); for()= 0 ; y<y—sizel; y + + ) { printf(" 画像 1 から画像 2 への速度べクトルを求めています . yn"); だ処理開始 y-vctr[y][x] = 0 ; x-vctr[y][x] = 0 ; for()= 0 ; x<x—sizel; x + + ) { for(y=0; y<y_sizel; y 十十 ) だ速度場の画像の初期化 * / } while ( step く 2 Ⅱ step > 20 ) ; scanf("%d" &step); printf(" 速度べクトルを計算する画素間の距離 ( 2 ~ 20 ) : " ) ; do { 163
135 int min—range = 100 ; int max—range = 600 ; 6 立体認識 だ想定最小距離 [mm] / * 想定最大距離 [mm] static int range[MAX IMAGESIZE][MAX IMAGESIZE] ; だ距離 * / / * 左画像 , 右画像の対応する座標 * / int xL, yL, xR, yR; だ計測点の ( x , y , z ) 絶対座標 double xp, yp, zp; int min—dist, max-dist; だ計測した距離の最小 , 最大値 * / / * 距離データ用配列の初期化 for ()L = 0 ; yL < y_sizel; yL + + ) for(xL=O;xL<x size1;xL + + ) range [yL][xL] = 0 ; だ処理開始 * / printf ( " 左画像を基準にしてステレオマッチングを行います . vn"); for ()L = 0 ; yL く y_sizel; yL + + ) { printf("line %dYn",yL); for (xL= 0 ; xL<x sizel; xL + + ){ determine—corresponding—point( xL, yL, &xR, &yR ) ; calc—range—data( xL, yL, xR, yR, d, f, pixel—to mm, range[yL][xL] = (int)zp; / * 以降は計測結果を画像にするための後処理である . * / だ計測した距離を範囲 [min_range, max_range] 内に入れる for ()L = 0 ; yL < y—sizel; yL + + ) { for (xL= 0 ; xL<x sizel; xL + + ){ if ( range[yL][xL] く = min—range ) range[yL][xL] = min—range; if ( range[yL][xL] > max—range ) range[yL][xL] = max—range; だ距離の最小 , 最大値を求める * / min dist = INT MAX; max dist = INT MIN; for ( yL = 0 ; yL く y—sizel; yL + + ) { for (xL=0; xL<x sizel; xL + + ){ if ( range[yL][xL] く min dist ) min—dist = range[yL][xL] ; else if ( range[yL][xL] > max—dist ) max—dist = range[yL][xL] ;
62 3 2 値画像処理 image2[y][x] = 0 ; main( ) image2[y][x] = MAX BRIGHTNESS; image2[ys][xs] = = MAX BRIGHTNESS ) ys > = 0 & & ys く = y—size2 & & if ( xs > = 0 & & xs く = x—size2 & & ys = y + Freeman[i][1]; xs = x + Freeman[i][O] ; for ( i = 0 ; i < 8 ; i + + ) { image2[y][x] = 0 ; if ( image2[y][x] = GRAY ) { for ( x = 0 ; x く x_size2; x + + ) { for ( y = 0 ; y く y—sizeX y + + ) { だ後処理 * / image2 [ys][xs] = (unsigned char)fill value; imagel[ys][xs] = 0 ; ys = ys + Freeman[ chain—code[i] Ⅱ 1 ] ; xs = xs + Freeman[ chain—code[i] Ⅱ 0 ] ; for ( i = 0 ; i く num - 1 ; i + + ) { if ( num > 1 ) { image2 [ys][xs] = (unsigned char)fill value; imagel[ys][xs] = 0 ; xs = x; YS = Y' else ⅱⅡ value = GRAY; fill_value = MAX BRIGHTNESS; if ( num > threshold ) num = obtain—contour( x, Y ) ; だ輪郭線追跡 * / if ( imagel[y][x] = = MAX BRIGHTNESS ) { だ = 開始点 * / for ()= 0 ; x<x—sizel; x + + ) { for ()= 0;y<y—size1; y + + ) { だ処理開始 * /
148 #include"mypgm. h" 7 動画像処理 void copy_imagel—t0—image2( ) /*imagel の画像データを image2 へコピーする * / intx, y; / * ループ変数 * / x_size2 = x_sizel; y_size2 = y_sizel; for()= 0 ; y<y_sizel; y 十十 ) for(x=0;x<x—size1;x 十十 ) image2 [y][x] = imagel [y][x] ; void make difference—image( ) だループ変数 int x, y; int difference; だ差分の絶対値 * / if ( image2 [y][x] > max-dif ) for ( x = 0 ; x く x_size2; x + 十 ) for ( y = 0 ; y < y_size2; y + + ) だマスク画像の生成 * / } while ( max_dif < 1 Ⅱ max dif > 100 ) ; scanf("%d" &max_dif); printf ( " 差分の許容最大階調値 ( 1 ~ 100 ) : " ) ; do { printf ( " 差分画像からマスク画像を作ります . vn"); int max-dif, だ許容できる最大の差分値 * / int x, y; だループ変数響 void make mask image( ) image2 [y][x] = (unsigned char)difference; difference = abs( image2 [y][x] - imagel[y][x]); for ( x = 0 ; x く x_sizeX x + + ) { for ( y = 0 ; y < y_size2; y 十 + ) { printf(" 絶対値を求めて image2[y][x] に代入します . ¥が ' ) ; printf("framel と frame2 の画素ごとの階調値の差分の¥ n " ) ;