C言語 画像処理 二値化画像雑音(ゴマ塩雑音)除去についいて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
rampom
記事: 5
登録日時: 12年前
住所: 東京都

C言語 画像処理 二値化画像雑音(ゴマ塩雑音)除去についいて

#1

投稿記事 by rampom » 12年前

みなさん初めまして!!
大学で画像処理について学んでいるrampomと申します.
今日からこちらにお世話になり,C言語の習得に励んでいきたいと考えております.
この度,私は画像処理の雑音除去を行いたいと思い,C言語のプログラムを作成しました.
しかし,雑音除去のプログラムを作成するに当たり,かなりのエラーが出てしまい,二進も三進もいかなくなってしまいました・・・
そこで,大変恐縮ではございますが,以下に私の作成したプログラムを記載しますので,このプログラムの続きに雑音除去を行い,雑音を除去した画像を保存するプログラムを作成していただけないでしょうか.
私は,どのように組み込んだらいいのかが分かりません汗
ちなみに,画像はBMPで,雑音除去には収縮膨張膨張収縮処理を行うことが分かっています.プログラムの最後に収縮膨張膨張収縮処理のプログラムも記載します.
よろしくお願いします!!
開発環境は,gccです.
ちなみに,以下に示したプログラムは雑音除去のプログラムを省くと問題なく実行できます.

コード:

#include<stdio.h>
#define X_SIZE 2000/*画像の横サイズを定義*/
#define Y_SIZE 2000/*画像の縦サイズを定義*/

unsigned char screen[Y_SIZE][X_SIZE][3],		/*unsigned:符号無しの整数型、char:文字データ、screen[Y_SIZE][X_SIZE][3]:3次配列*/
		img_work[Y_SIZE][X_SIZE][3];		/*screen[y][x][color(b=0,g=1,r=2と割り当てられる)]	0~255を値として取る*/
int main() 
{

	FILE *fp;	/*ファイルポインタの宣言*/
	unsigned char header[54];			/*unsigned:符号無しの整数型、char:文字データ、header[54]:0~53の1次配列*/
									
	int thresh;	/*閾値(0~255)*/
	char input_file[128],gray_file[128],hist_file[128],ttv_file[128],goma_file[128];	/*ファイル名の配列を定義*/
 	unsigned char Light[256]={0};	    /*ヒストグラム白黒濃淡配列を定義*/

	/*------------画像ファイルを読み込む------------*/

	printf("処理を行う画像ファイル名を入力してください.(拡張子:bmp)\n---");
	scanf("%s",input_file);					/*入力ファイル名を指定*/
	printf("処理を行う画像ファイルは「 %s 」です.\n\n",input_file);
	fp=fopen(input_file,"rb"); 	/* 処理する画像をオープンする	
					Windowsビットマップ形式 X_SIZE*Y_SIZEピクセル,24ビットカラー、rb:バイナリデータの読み込みに使用 */
	if((fp=fopen(input_file,"rb"))==NULL){		/*ファイルが開けない場合のエラー表示*/
		printf("画像ファイルが正常に開けませんでした.\n");
		exit(1);
	}
	fread(header,1,54,fp); 					/* ヘッダ(54バイト)を飛ばす */
	fread(screen,1,X_SIZE*Y_SIZE*3,fp); /* 残りはデータ(最下行から順に入る) */
	fclose(fp);

	/*------------カラー画像をグレースケールに変換する------------*/

	int X,Y,k,col;
	for(X=0;X<X_SIZE;X++){
		for(Y=0;Y<Y_SIZE;Y++){
			for(col=0;col<=2;col++){
				img_work[Y][X][col]=0.1145*screen[Y][X][0]
					+0.5866*screen[Y][X][1]+0.2989*screen[Y][X][2];	
			}
		}
	}

	/*------------グレースケール画像を保存する------------*/

	printf("グレースケールにする画像ファイル名を入力してください.(拡張子:bmp)\n---");
	scanf("%s",gray_file);		/*グレースケールとするファイル名を指定*/
	fp=fopen(gray_file,"wb");	/*処理した画像を書き込むファイルをオープンする*/
	if((fp=fopen(gray_file,"wb"))==NULL){		/*ファイルが開けない場合のエラー表示*/
		printf("画像ファイルが正常に開けませんでした.\n");
		exit(1);
	}
	fwrite(header,1,54,fp); /* ヘッダ */
	fwrite(img_work,1,X_SIZE*Y_SIZE*3,fp); /* データ */
	fclose(fp);
	printf("グレースケールの画像ファイル「 %s 」を保存しました.\n\n",gray_file);
	
	/*------------白黒濃淡情報を抽出する------------*/

	for(Y=0;Y<Y_SIZE;Y++){
		for(X=0;X<X_SIZE;X++){
			for(k=0;k<256;k++){
				if(k==img_work[Y][X][0]){/*画像配列のデータを明度配列に代入*/
					Light[k]++;
				}
			}
		}
	}

	/*------------判別分析法により閾値を決定する------------*/

	int s,i;
	double n1,n2,m1,m2;
	double v[256],vmax;

	for(s=1;s<256;s++){
		n1=0;
		m1=0;
		for(i=0;i<s;i++){
			n1+=Light[i];
			m1+=i*Light[i];
		}
		if(n1==0.0){
			m1=0.0;
		}else{
			m1/=n1;
		}
		n2=0;
		m2=0;
		for(i=s;i<256;i++){
			n2+=Light[i];
			m2+=i*Light[i];
		}
		if(n2==0.0){
			m2=0.0;
		}else{
			m2/=n2;
		}
		v[s]=n1*n2*(m1-m2)*(m1-m2);
	}

	vmax=0;
	s=0;
	for(i=1;i<256;i++){
		if(v[i]>vmax){
			vmax=v[i];
			s=i;
			thresh=s;/*求められた値をthreshに代入*/
		}
	}


	/*------------2値化処理を行う------------*/


	for(X=0;X<X_SIZE;X++){
		for(Y=0;Y<Y_SIZE;Y++){
			if(img_work[Y][X][0]<=thresh){
				for(col=0;col<3;col++){
					img_work[Y][X][col]=0;	/*閾値以下の場合、画素の値を0とする*/
				}
			}else{
				for(col=0;col<3;col++){
					img_work[Y][X][col]=255;/*閾値以上の場合、画素の値を255とする*/
				}
			}
		}
	}

	/*------------2値化画像を保存する------------*/

	printf("二値化する画像ファイル名を入力してください.(拡張子:bmp)\n---");
	scanf("%s",ttv_file);					/*二値化するファイル名を指定*/

	fp=fopen(ttv_file,"wb");	/*2値化した画像を書き込むファイルをオープンする*/
	if((fp=fopen(ttv_file,"wb"))==NULL){		/*ファイルが開けない場合のエラー表示*/
		printf("画像ファイルが正常に開けませんでした.\n");
		exit(1);
	}
	fwrite(header,1,54,fp); /* ヘッダ */
	fwrite(img_work,1,X_SIZE*Y_SIZE*3,fp); /* データ */
	fclose(fp);
	printf("閾値を%dとして処理を行いました.\n",thresh);
	printf("二値化処理の画像ファイル「 %s 」を保存しました.\n",ttv_file);
	printf("全ての作業が終了しました.\n");

	return 0;
}
/*----------雑音除去----------*/
	/*----------膨張処理----------*/
	int m,n;
		in[m][n]=img_work[Y][X][col];
	   out[m][n]=goma[Y_SIZE][X_SIZE][3]
		for(m=1;m<Y_SIZE-1;m++)
		for(n=1;n<X_SIZE-1;m++){
			out[m][n]=in[m][n];
			if(in[m-1][n-1]==HIGH)out[m][n]=HIGH;
			if(in[m-1][n  ]==HIGH)out[m][n]=HIGH;
			if(in[m-1][n+1]==HIGH)out[m][n]=HIGH;
			if(in[m  ][n-1]==HIGH)out[m][n]=HIGH;
			if(in[m  ][n+1]==HIGH)out[m][n]=HIGH;
			if(in[m+1][n-1]==HIGH)out[m][n]=HIGH;
			if(in[m+1][n  ]==HIGH)out[m][n]=HIGH;
			if(in[m+1][n+1]==HIGH)out[m][n]=HIGH;
		}

	/*----------収縮処理----------*/
		for(m=1;m<Y_SIZE-1;m++)
		for(n=1;n<X_SIZE-1;m++){
			out[m][n]=in[m][n];
			if(in[m-1][n-1]==LOW)out[m][n]=LOW;
			if(in[m-1][n  ]==LOW)out[m][n]=LOW;
			if(in[m-1][n+1]==LOW)out[m][n]=LOW;
			if(in[m  ][n-1]==LOW)out[m][n]=LOW;
			if(in[m  ][n+1]==LOW)out[m][n]=LOW;
			if(in[m+1][n-1]==LOW)out[m][n]=LOW;
			if(in[m+1][n  ]==LOW)out[m][n]=LOW;
			if(in[m+1][n+1]==LOW)out[m][n]=LOW;
		}
添付ファイル
oreryu改.c
(4.19 KiB) ダウンロード数: 256 回
最後に編集したユーザー rampom on 2013年6月30日(日) 00:38 [ 編集 1 回目 ]

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: C言語 画像処理 二値化画像雑音(ゴマ塩雑音)除去についいて

#2

投稿記事 by softya(ソフト屋) » 12年前

まず大きな間違いは、C言語の場合C99規格に対応してるコンパイラで、C99のオプションが有効じゃないと関数先頭にしか変数宣言は出来ません。
つまり、途中にあるint X,Y,k,col;とかが全部エラーになっているわけです。
開発環境が書いてないですが、VC++でしょうか?
途中宣言が可能なcppでコンパイルするか、変数宣言を関数に最初に持ってくれば解決します。
あるいはgccなら-std=c99を指定するかですね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: C言語 画像処理 二値化画像雑音(ゴマ塩雑音)除去についいて

#3

投稿記事 by usao » 12年前

「エラーがたくさんでました」では何も伝わらないと思いませんか?
エラーメッセージくらい示しましょうよ.
>以下に示したプログラムは雑音除去のプログラムを省くと問題なく実行できます.
エラーが大量にあるのに動くのでしょうか? まったく意味不明です.
(まさかとは思いますが,本当に貼られているとおりに
 int main(){...}の後ろに唐突にコードを書いているのでしょうか?)

・毎回2重にfopenする意味があるのでしょうか?
・大学で画像処理がどうの という話ですが,今回のコードはその場限りの使い捨てのコードなのでしょうか?
 これからいろいろいじっていく必要があるのであれば,main()内に長々と書くのはお勧めしません.

閉鎖

“C言語何でも質問掲示板” へ戻る