画像処理

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
mai

画像処理

#1

投稿記事 by mai » 11年前

私が今やろうとしていることは、元画像をランダム画像と重ね合わせて、元画像のデータとランダム画像データを否定排他的論理和で重ね合わせ、元画像を暗号化にし、この暗号化した画像を復号化するためにさきほど重ね合わせて暗号化したデータとランダムデータの反転したものの重ね合わせて復号化すると、元画像の黒の部分だけが元に戻るというプログラムを作ろうとしています。
画像は元画像もランダム画像も縦横256×256で、画像データを出したテキストファイルはタブ区切りとなっています。二つとも二値化しています。黒が255で、白が0となっています。visual studio 2005を使っています。
この下のプログラムを起動して、text.txtを見ても暗号化した(元画像データとランダム画像データの否定排他的論理和での重ね合わせ)部分と復号化した(否定排他的論理和で重ね合わせたものとランダムデータの反転したものの重ね合わせ部分)部分がうまくできてないです。復号化した部分のテキストデータは全て0になっています。
これは元画像とランダム画像のテキストデータが変数aとbにちゃんと入ってないのでしょうか?
それともほかに不備があるのでしょうか?
もしどこを修正するのか分かる方は、どこをどう修正するのか教えてください。
よろしくお願いします。


コード:

#include<stdio.h>

int main(void){
FILE *file;
file = fopen("test.txt","w");
	//元画像
	FILE *fp1;
	char *fname1="C:\\Documents and Settings\\2013Sotsuken\\My Documents\\test\\hosi1.txt";
	int c,j,k,s,t,u,v;

	int **a=new int*[512];
	for(int i=0;i<512;i++){
		a[i]=new int[512];
	}

	fp1=fopen(fname1,"r");

	if(fp1==NULL){
		fprintf(file,"%sファイルが開けません\n",fname1);
		return -1;
	}
	s=t=0;
	for(s=0;s<512;s++){
		for(t=0;t<340;t++){
			c=fgetc(fp1);
			if(c=='0')
				a[s][t]=0;
			else if(c=='255')
				a[s][t]=255;
			fprintf(file,"%c",c);
		}
	}
   
	fprintf(file,"\n");
    fprintf(file,"\n\n");




//ランダム画像
	
    FILE *fp2;
	char *fname2="C:\\Documents and Settings\\2013Sotsuken\\My Documents\\test\\ekisyou.txt";
	int d;

	int **b=new int*[512];
	for(int i=0;i<512;i++){
		b[i]=new int[512];
	}


	fp2=fopen(fname2,"r");

	if(fp2==NULL){
		fprintf(file,"%sファイルが開けません\n",fname2);
		return -1;
	}
	u=v=0;
	for(u=0;u<512;u++){
		for(v=0;v<340;v++){
			d=fgetc(fp2);
			if(d=='0')
				b[u][v]=0;
                else if(d=='255')
				b[s][t]=255;
			
			fprintf(file,"%c",d);
		}
	}
	fprintf(file,"\n\n");



	
//元画像データとランダム画像データの否定排他的論理和での重ね合わせ

	int **m=new int*[255];
	for(int i=0;i<256;i++){
		m[i]=new int[255];
	}

	for(j=0;j<256;j++){
		for(k=0;k<256;k++){
		if(a[j][k]==0&&b[j][k]==0 || a[j][k]==255&&b[j][k]==255)
				m[j][k]=255;
			else
				m[j][k]=0;
			fprintf(file,"%d\t",m[j][k]);
		}
		fprintf(file,"\n");
	}
	fprintf(file,"\n\n");

	//否定排他的論理和で重ね合わせたものとランダム画像データの反転したものの重ね合わせ

	int **x=new int*[255];
	for(int i=0;i<256;i++){
		x[i]=new int[255];
	}


	for(j=0;j<256;j++){
		for(k=0;k<256;k++){
			if(m[j][k]==255&&b[j][k]==255)
				x[j][k]=255;
			else
				x[j][k]=0;
			fprintf(file,"%d\t",x[j][k]);
		}
		fprintf(file,"\n");
	}


	//for(int i=0;i<256;i++){
	//	delete[] a[i];
	//}
	//delete[] a;

	//for(int i=0;i<256;i++){
	//	delete[] b[i];
	//}
	//delete[] b;

	//for(int i=0;i<256;i++){
	//	delete[] m[i];
	//}
	//delete[] m;

	//for(int i=0;i<256;i++){
	//	delete[] x[i];
	//}
	//delete[] x;


 fclose(fp1);
fclose(fp2);
fclose(file);
	return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 画像処理

#2

投稿記事 by みけCAT » 11年前

仕様を読解中ですが、とりあえず

コード:

if(c=='0')
    a[s][t]=0;
else if(c=='255')
    a[s][t]=255;
という処理は不自然だと思います。
bについても同じです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 画像処理

#3

投稿記事 by みけCAT » 11年前

mai さんが書きました:画像は元画像もランダム画像も縦横256×256で
mai さんが書きました:

コード:

    int **m=new int*[255];
    for(int i=0;i<256;i++){
        m[i]=new int[255];
    }
配列の容量が足りません。バッファオーバーランによるアクセス違反のリスクがあります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 画像処理

#4

投稿記事 by みけCAT » 11年前

入力ファイルのフォーマットを詳しく示していただけますか?
著作権などが大丈夫なら、入力ファイルの例をアップロードしていただけるとわかりやすいです。

アップローダーの例
http://www.axfc.net/uploader/
http://kie.nu/
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

mai

Re: 画像処理

#5

投稿記事 by mai » 11年前

cは二次元配列ではないので、変数aでcに入ったデータを二次元配列にしたのですが、どのようになおせばいいですか?

ランダム画像・・・http://kie.nu/.1D9e
元画像・・・http://kie.nu/.1D9d

アップロードしました。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 画像処理

#6

投稿記事 by みけCAT » 11年前

残念ながら、提示されたプログラムでJPEGフォーマットのファイルを読み込むことはできません。
また、JPEGファイルの読み取りはかなり難しいと言われています。
libjpegを利用するか、PPMなど他の画像形式を利用することを検討してください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

mai

Re: 画像処理

#7

投稿記事 by mai » 11年前

この2枚の画像はテキストファイルに数値化した値をだしています。そのテキストファイルは読み込むことはできているのですが・・・・・
ですのでこのファイルが読み込めると仮定して教えてください。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 画像処理

#8

投稿記事 by みけCAT » 11年前

ファイルが読み込めていないと疑っているので、入力ファイルの提示を要求しました。
どうやって読み込むことができていることを確認したのですか?

計算処理の部分は、
m[j][k]=(a[j][k]^b[j][k])^0xFF
x[j][k]=(m[j][k]&b[j][k])
という仕様なら、合っていると思います。
復号化のときに使用する「重ね合わせ」の計算式がわかりません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 画像処理

#9

投稿記事 by みけCAT » 11年前

こちらでlibjpegを利用して実験したところ、復号化後のデータが全て0になることはありませんでした。

コード:

#include<stdio.h>
#include<stdlib.h>
#include<jpeglib.h>

int** loadJpeg(const char* name) {
	int **a=new int*[512];
	for(int i=0;i<512;i++){
		a[i]=new int[512];
	}
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	cinfo.err = jpeg_std_error( &jerr );
	jpeg_create_decompress( &cinfo );
	FILE* infile=fopen(name,"rb");
	jpeg_stdio_src( &cinfo, infile );
	jpeg_read_header( &cinfo, TRUE );
	jpeg_start_decompress( &cinfo );
	JSAMPROW buf=(JSAMPROW)malloc(sizeof(JSAMPLE)*3*512);
	for(int i=0;i<cinfo.image_height;i++) {
		jpeg_read_scanlines(&cinfo,&buf,1);
		for(int j=0;j<cinfo.image_width;j++) {
			if(buf[j*3]+buf[j*3+1]*buf[j*3+2]>=128*3) {
				a[i][j]=0;
			} else {
				a[i][j]=255;
			}
		}
	}
	free(buf);
	return a;
}

int main(void){
	FILE *file;
	file = fopen("test.txt","w");
	//元画像
//	char *fname1="hosi1.txt";
	char *fname1="moto.jpg";
	int c,j,k,s,t,u,v;

	int** a=loadJpeg(fname1);

	fprintf(file,"\n");
	fprintf(file,"\n\n");




	//ランダム画像

//	char *fname2="ekisyou.txt";
	char *fname2="random.jpg";
	int d;

	int** b=loadJpeg(fname2);

	fprintf(file,"\n\n");




	//元画像データとランダム画像データの否定排他的論理和での重ね合わせ

	int **m=new int*[255];
	for(int i=0;i<256;i++){
		m[i]=new int[255];
	}

	for(j=0;j<256;j++){
		for(k=0;k<256;k++){
			if(a[j][k]==0&&b[j][k]==0 || a[j][k]==255&&b[j][k]==255)
			m[j][k]=255;
			else
			m[j][k]=0;
			fprintf(file,"%d\t",m[j][k]);
		}
		fprintf(file,"\n");
	}
	fprintf(file,"\n\n");

	//否定排他的論理和で重ね合わせたものとランダム画像データの反転したものの重ね合わせ

	int **x=new int*[255];
	for(int i=0;i<256;i++){
		x[i]=new int[255];
	}


	for(j=0;j<256;j++){
		for(k=0;k<256;k++){
			if(m[j][k]==255&&b[j][k]==255)
			x[j][k]=255;
			else
			x[j][k]=0;
			fprintf(file,"%d\t",x[j][k]);
		}
		fprintf(file,"\n");
	}


	//for(int i=0;i<256;i++){
	//  delete[] a[i];
	//}
	//delete[] a;

	//for(int i=0;i<256;i++){
	//  delete[] b[i];
	//}
	//delete[] b;

	//for(int i=0;i<256;i++){
	//  delete[] m[i];
	//}
	//delete[] m;

	//for(int i=0;i<256;i++){
	//  delete[] x[i];
	//}
	//delete[] x;


	fclose(file);
	return 0;
}
出力データを添付します。

【追記】
このコードでは、前述のバッファオーバーランのバグは修正していません。

【2014/2/3 追記】
重要:前のコードは仕様を誤解していました
コードと出力データを差し替えました。
添付ファイル
test.txt
出力データ(修正版)
(342.6 KiB) ダウンロード数: 109 回
最後に編集したユーザー みけCAT on 2014年2月03日(月) 21:26 [ 編集 1 回目 ]
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Poco
記事: 161
登録日時: 14年前

Re: 画像処理

#10

投稿記事 by Poco » 11年前

三毛猫さんのコメントと被りますが、演算周りをはっきりさせてください。

元画像の画素をx、ランダム画像の画素をy、暗号化処理をf、暗号化後の画素をm、復号処理をg、復号後の画素をzとしたとき、
画素は2値データなので白を0、黒を1とするとx,y,z∈{0,1}
んで、
 m=f(x,y)
 z=g(m、¬y)
 fはx=y⇒1、x≠y⇒0(※これは84行目から87行目までのソースから推定)
で、
 x=0かつy=0⇒m=1,z=???
 x=0かつy=1⇒m=0,z=???
 x=1かつy=0⇒m=0,z=1
 x=1かつy=1⇒m=1,z=1
gの式で↑を表すと順番に
 ???=g(1,1)
 ???=g(0,0)
 1=g(0,1)
 1=g(1,0)
これを満たすgという操作を94行目のコメント以降(というか104行目の)を行わないといけないんですよね?
しかしながらソースを見るに、gを論理積としていますよね?
そうすると
 0=g(0,1)
 0=g(1,0)
となるので、ほしい結果にならない気がするのですが。
gを論理和とすれば、
 1=g(1,1)
 0=g(0,0)
 1=g(0,1)
 1=g(1,0)
となり、元画像が黒の時は黒に、白の時はランダム画像と画素の反対の画素が表示されるんじゃないでしょうか?
間違っていたらゴメンナサイ。

mai

Re: 画像処理

#11

投稿記事 by mai » 11年前

みけCATさん
この2枚の画像でもう一度テキストファイルを出す処理をやってくれませんか?
そして出力データを添付して欲しいです。
頑張ったんですがlibjpegが使えませんでした。

http://kie.nu/.1EeN・・・・ランダム画像
http://kie.nu/.1EeO・・・・元画像

この2枚の画像をアップロードしたのでこの出力結果が欲しいです。
本当にお願いします。

mai

Re: 画像処理

#12

投稿記事 by mai » 11年前

すいません。
画像間違えました。

ランダム画像・・・・http://kie.nu/.1Ehr
元画像・・・・http://kie.nu/.1Ehz

この2枚でよろしくお願いします。
すいません。

mai

Re: 画像処理

#13

投稿記事 by mai » 11年前

みけCATさん見ていますか?
本当にお願いします。

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

Re: 画像処理

#14

投稿記事 by usao » 11年前

オフトピック
>この2枚の画像はテキストファイルに数値化した値をだしています。そのテキストファイルは読み込むことはできているのですが・・・・・
>ですのでこのファイルが読み込めると仮定して教えてください。

という話だったならば,
"JPEGを読み込む" なんていう主題と離れたことをできるできないとかで時間を浪費するよりも
さっさと本題の処理アルゴリズム内容側を検証した方が良いのではないかと思うのですが.
(他力本願で出力データを入手するよりも,内容面の話をされているPocoさんの側にきちんと応答された方が有益なのでは?)

追記:
・文面から察するに,やりたいことは
  符号化 : m = NOT( a XOR b )   複合化 : x = m XOR NOT(b)
 ということなんだろうな,とは思うけど.
・どうしてもJPEG読みたいんだ!とかいうことなら,画像ロード後に2値化の必要があるだろう点に気を付けてください.

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 画像処理

#15

投稿記事 by みけCAT » 11年前

mai さんが書きました:みけCATさん見ていますか?
本当にお願いします。
ごめんなさい。
昨日は期末試験に向けた準備で忙しかったので、パソコンを開きませんでした。
そんなに緊急の依頼だとは思いませんでした。

【追記】
仕様を誤解したプログラムによる出力のデータを削除しました。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 画像処理

#16

投稿記事 by みけCAT » 11年前

申し訳ありません、今まで仕様を誤解していました。
No: 9のコードと出力を修正しました。

No: 12に対する出力を添付します。
また、実行可能バイナリも添付しますので、ご活用ください。
バッファオーバーランのバグを修正し、入出力ファイルもコマンドラインで指定可能にしました。
添付ファイル
output_1Ehz_1Ehr.txt
No: 12に対する出力
(345.03 KiB) ダウンロード数: 121 回
gazouseisei2.zip
実行可能バイナリ+ソースコード
(93.04 KiB) ダウンロード数: 117 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

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