相関法の計算の仕方 – プログラミング – Home

通知
すべてクリア

相関法の計算の仕方

固定ページ 1 / 2

寝れない日々
 寝れない日々
(@寝れない日々)
ゲスト
結合: 24年前
投稿: 8
Topic starter  

画像処理としてパターンマッチングのプログラムを作らなければならないのですが
なにぶんプログラムにうといものでどうしてよいやらわからなくて困ってます。
相関法の計算式までは調べたのですがそれをどうプログラムしてよいか
見当もつかないのが現状です。
本を調べても基本的な総和は載っていてもちょっと厄介な計算に関しては
載っていなくてまいっています。
もしよろしければどなたか教えてください。
よろしくおねがいします。


引用解決済
トピックタグ
CdS
 CdS
(@CdS)
ゲスト
結合: 24年前
投稿: 176
 

画像処理の専門でない人は「パターンマッチング」だとか「相関法」という言葉は知らないはずです。
少なくとも私は全く分かりません。
その上「厄介な計算」と言われてもどうしたらいいのか分かりません。

プログラミングに関してならアドバイスできるかと思いますが、それらが一体どういうものかを簡単に
でも説明してもらわなければ回答はまず得られないと思います。
かといって延々と説明されても困りますが。

そういう訳で回答がないのだと思いますよ。


返信引用
寝れない
 寝れない
(@寝れない)
ゲスト
結合: 24年前
投稿: 1
 

そうですね。すいませんでした。
大体説明するととりあえず∑の計算をしなければなりません。
ただ範囲が決まってないところが困ってるところです。
1からNまでという不規則なところがよくわからないのです。
それに加えてそこに使う変数に別のファイルにあるデータを
読み込みたいのですがそこでもかなり困ってます。


返信引用
CdS
 CdS
(@CdS)
ゲスト
結合: 24年前
投稿: 176
 

>大体説明するととりあえず∑の計算をしなければなりません。
>ただ範囲が決まってないところが困ってるところです。
>1からNまでという不規則なところがよくわからないのです。

と言われてもこちらとしてはどうすることもできないので、計算の部分はご自分で行ってください。
あくまでもプログラミングのことしかアドバイスできません。

>それに加えてそこに使う変数に別のファイルにあるデータを
>読み込みたいのですがそこでもかなり困ってます。

MFCを使っているのならCFile、使っていないのならCreateFile, ReadFile等を調べてください。
どう分からないかを書いてもらわないと、こういう回答しかできません。

#最初の投稿でもそうですが、「寝れない(日々)」さんが今どう困っているかなんてこっちは分からない訳ですよ...。


返信引用
寝れない日々
 寝れない日々
(@寝れない日々)
ゲスト
結合: 24年前
投稿: 8
Topic starter  

すいませんでした。
一応自分なりにプログラムは組んでみたのですが
EXEファイルを実行しようとすると動かなくなるので
どうしたらよいかアドバイスしていただければ幸いです。

#include <stdio.h>
#include <math.h>
#include <process.h>
#define n 1000000 /*データの数*/
#define N 1600 /*N pixel*/

void read(float x1[],float x2[],float y1[],float y2[],float I[],float M[]);
float calculate(float I[],float M[]);

main()
{
float x1[n],x2[n],y1[n],y2[n];
float I[n],M[n];
float r;
read(x1,x2,y1,y2,I,M);
r=calculate(I,M);
printf(r=%f\n,r); /*相関係数*/
printf(↑相関係数\n);
}

/*メインプログラムはここまで*/

/*こっからはサブルーチン*/

/*ファイルの読み込み*/

void read(float x1[],float x2[],float y1[],float y2[],float I[],float M[])

{
int i;
FILE *input1,*input2;

input1 = fopen(data1.txt,r);
input2 = fopen(data2.txt,r);

if (input1 == NULL){
printf(ファイルが存在しません!\n);
exit(-1);
}
if (input2 == NULL){
printf(ファイルが存在しません!\n);
exit(-1);
}

while(
(fscanf(input1,%d\t%d\t%f\n,&x1[i],&x2[i],&I[i]) !=EOF)
/*一つ目のファイルから読み込み*/
&&
(fscanf(input2,%d\t%d\t%f\n,&x2[i],&x2[i],&I[i]) !=EOF)
/*二つ目のファイルから読み込み*/
&&
(i<n)
)

fclose(input1);
fclose(input2);
}

/*相関係数の計算*/

float calculate(float I[],float M[])
{
int i;
float r;
float ans1,ans2,ans3;
float sum1=0,sum2=0,sum3=0,sum4=0,sum5=0;

for(i=0;i<=n;i++){
sum1+=I[i];
sum2+=M[i];
sum3+=I[i]*M[i];
sum4+=I[i]*I[i];
sum5+=M[i]*M[i];
}

ans1=N*sum3-sum1*sum2;
ans2=N*sum4-sum1*sum1;
ans3=N*sum5-sum2*sum2;
r=ans1/sqrt(ans2*ans3);
return r;
}

これがソースなんですがファイルの読み込みの部分があまり自信ないです。
よろしくお願いします。


返信引用
TAKA
 TAKA
(@TAKA)
ゲスト
結合: 24年前
投稿: 117
 

わかっているだけでも
readのなかがだめですね

> while(
> (fscanf(input1,%d\t%d\t%f\n,&x1[i],&x2[i],&I[i]) !=EOF)
> /*一つ目のファイルから読み込み*/
> &&
> (fscanf(input2,%d\t%d\t%f\n,&x2[i],&x2[i],&I[i]) !=EOF)
> /*二つ目のファイルから読み込み*/
> &&
> (i<n)
> )
iの初期化がない
ファイル1のよみこみと2の読み込みにおなじ変数を定義してる
x1を一回x2を3回Iを2回
デバッグをしやすいように一文に書くのではなく
分けて書いて少しづつデバッグできるようにしないと何もできませんね。
またx1等がfloatなのに%dをつかってますね

>これがソースなんですがファイルの読み込みの部分があまり自信ないです
わかっているなら調べやすいようにソースを整理してデバッグしましょう。


while(i<n){
if (fscanf(input1,%f,x1[i]) == EOF) {
break;
}
if (fscanf(input1,%f,x2[i]) == EOF) {
break;
}



i++;
}


返信引用
寝れない日々
 寝れない日々
(@寝れない日々)
ゲスト
結合: 24年前
投稿: 8
Topic starter  

すばやいレスでのアドバイスありがとうございます。

うち間違ったところを修正してみました。
この場合本来ならまったく同じデータを使わない限り
r=1.000000とはならないはずなのですが
どんなデータを使ってもr=1.000000 or r=-1.000000の両端の値しか
返してくれません。これはどこに原因があるのでしょう?
(-1.000000<=r<=1.000000がrのとりうる範囲です)
それとn,Nの値は本当ならnが6000000くらい、Nは10000くらいで
処理をしたいのですがそれだとエラーになってしまいます。
これはどのようにすればよいですか?

#include <stdio.h>
#include <math.h>
#include <process.h>
#define n 3 /*データの数*/
#define N 10 /*N pixel*/

void read(float x1[],float x2[],float y1[],float y2[],float I[],float M[]);
float calculate(float I[],float M[]);

main()
{
float x1[n],x2[n],y1[n],y2[n];
float I[n],M[n];
float r;
read(x1,x2,y1,y2,I,M);
r=calculate(I,M);
printf(r=%f\n,r); /*相関係数*/
printf(↑相関係数\n);
}

/*メインプログラムはここまで*/

/*こっからはサブルーチン*/

/*ファイルの読み込み*/

void read(float x1[],float x2[],float y1[],float y2[],float I[],float M[])

{
int i=0;
FILE *input1,*input2;

input1 = fopen(data1.txt,r);
input2 = fopen(data2.txt,r);

if (input1 == NULL){
printf(ファイルが存在しません!\n);
exit(-1);
}
if (input2 == NULL){
printf(ファイルが存在しません!\n);
exit(-1);
}

while(
(fscanf(input1,%f\t%f\t%f\n,&x1[i],&y1[i],&I[i]) !=EOF)
/*一つ目のファイルから読み込み*/
&&
(fscanf(input2,%f\t%f\t%f\n,&x2[i],&y2[i],&M[i]) !=EOF)
/*二つ目のファイルから読み込み*/
&&
(i<n)
)

fclose(input1);
fclose(input2);
}

/*相関係数の計算*/

float calculate(float I[],float M[])
{
int i;
float r;
float ans1,ans2,ans3;
float sum1=0,sum2=0,sum3=0,sum4=0,sum5=0;

for(i=0;i<=n;i++){
sum1+=I[i];
sum2+=M[i];
sum3+=I[i]*M[i];
sum4+=I[i]*I[i];
sum5+=M[i]*M[i];
}

ans1=N*sum3-sum1*sum2;
ans2=N*sum4-sum1*sum1;
ans3=N*sum5-sum2*sum2;
r=ans1/sqrt(ans2*ans3);
return r;
}

非常に面倒な質問でしょうがよろしくおねがいします。


返信引用
TAKA
 TAKA
(@TAKA)
ゲスト
結合: 24年前
投稿: 117
 

前回にも書きましたが
> while(
> (fscanf(input1,%f\t%f\t%f\n,&x1[i],&y1[i],&I[i]) !=EOF)
> /*一つ目のファイルから読み込み*/
> &&
> (fscanf(input2,%f\t%f\t%f\n,&x2[i],&y2[i],&M[i]) !=EOF)
> /*二つ目のファイルから読み込み*/
> &&
> (i<n)
> )
わけてデバッグしましょう。
これはiの値が更新されないため、x1[0]以外は未定義のデータです。
最後までi=0のため
i++ がないでしょう?
後はどこまで動いてるかデバッグすればいいはずです。
ステップ実行すれば後はできるはずです。
I・Mにきちんとデータがはいっているか確認すれば分かったはずです。
人にたよるまえに、そのくらいはしましょうね。


返信引用
NGA
 NGA
(@NGA)
ゲスト
結合: 24年前
投稿: 98
 

>それとn,Nの値は本当ならnが6000000くらい、Nは10000くらいで
>処理をしたいのですがそれだとエラーになってしまいます。
>これはどのようにすればよいですか?

ざっと計算してみると、90MBを超えているようですね。
それではスタックオーバーフローも当然です。
動的に確保するなり、もっと小さいサイズでも動くように変更するなりしないといけませんね。


返信引用
寝れない日々
 寝れない日々
(@寝れない日々)
ゲスト
結合: 24年前
投稿: 8
Topic starter  

すいませんでした。
もう一度やりなおしてみます。


返信引用
寝れない日々
 寝れない日々
(@寝れない日々)
ゲスト
結合: 24年前
投稿: 8
Topic starter  

すいませんでした。
もう一度やりなおしてみます。


返信引用
寝れない日々
 寝れない日々
(@寝れない日々)
ゲスト
結合: 24年前
投稿: 8
Topic starter  

読み込みに関する部分ではうまくいきました。
オーバーフローしないようにreadの中で相関係数の計算を
してしまいたいのですがそのときwhileの中でsum1~sum5を
計算するにはどうしたらよいのですか?
今はwhileが二つになってしまったのでsum3の処理がわからないです。


返信引用
TAKA
 TAKA
(@TAKA)
ゲスト
結合: 24年前
投稿: 117
 

参考までに今のプログラムをみるだけではこんな感じにします。
readの中ですが。
また、後で使わないならI・Mは配列にしません。
説明に必要ない部分は省いてます。あしからず・・・

float I, M;
float sum1=0.0f,sum2=0.0f,sum3=0.0f,sum4=0.0f,sum5=0.0f;

for (i = 0; i <= n; i++) {
/*一つ目のファイルから読み込み*/
if (fscanf(input1,%f\t%f\t%f\n,&x1[i],&y1[i],&I) == EOF) {
// エラーである又は終了を明記
break;
}
/*二つ目のファイルから読み込み*/
if (fscanf(input2,%f\t%f\t%f\n,&x2[i],&y2[i],&M) == EOF) {
// エラーである又は終了を明記
break;
}
sum1 += I;
sum2 += M;
sum3 += I * M;
sum4 += I * I;
sum5 += M * M;
}
if (エラーでないなら) {
// 以下計算
}


返信引用
ねれない日々
 ねれない日々
(@ねれない日々)
ゲスト
結合: 24年前
投稿: 1
 

TAKAさん毎回アドバイスありがとうございます。
自分なりにがんばってみたのですが、
データの数がファイル1とファイル2でちがうとき
sum3の値がおかしくなります。
これをなおすにはどのようにすればよいのですか?

#include <stdio.h>
#include <math.h>
#include <process.h>
#define n 1000 /*データの数*/
#define N 1000 /*N pixel*/

float read(float x1[],float x2[],float y1[],float y2[],float I[],float M[]);

main()
{
float x1[n],x2[n],y1[n],y2[n];
float I[n],M[n];
double r;
read(x1,x2,y1,y2,I,M);

}

/*メインプログラムはここまで*/

/*こっからはサブルーチン*/

/*ファイルの読み込み*/

float read(float x1[],float x2[],float y1[],float y2[],float I[],float M[])

{
int i=0;
int j=0;
float sum1=0.0f,sum2=0.0f,sum3=0.0f,sum4=0.0f,sum5=0.0f;
float ans1,ans2,ans3;
float r;
FILE *input1,*input2;

char filename1[30];
char filename2[30];

printf(入力ファイル1=);
gets(filename1);
printf(入力ファイル2=);
gets(filename2);

input1 = fopen(filename1,r);
input2 = fopen(filename2,r);

if (input1 == NULL){
printf(ファイル1が存在しません!\n);
exit(-1);
}
if (input2 == NULL){
printf(ファイル2が存在しません!\n);
exit(-1);
}

while((fscanf(input1,%f\t%f\t%f\n,&x1[i],&y1[i],&I[i]) !=EOF)){
/*一つ目のファイルから読み込み*/
printf(%d %f %f %f\n,i,x1[i],y1[i],I[i]);
sum1+=I[i];
sum4+=I[i]*I[i];
i++;
}
i=0;
j=0;
while((fscanf(input2,%f\t%f\t%f\n,&x2[j],&y2[j],&M[j]) !=EOF)){
/*二つ目のファイルから読み込み*/
printf(%d %f %f %f\n,j,x2[j],y2[j],M[j]);
sum2+=M[j];
sum5+=M[j]*M[j];
sum3+=I[j]*M[j];
j++;
}

printf(sum1r=%f\n,sum1);
printf(sum2r=%f\n,sum2);
printf(sum3r=%f\n,sum3);
printf(sum4r=%f\n,sum4);
printf(sum5r=%f\n,sum5);

ans1=N*sum3-sum1*sum2;
ans2=N*sum4-sum1*sum1;
ans3=N*sum5-sum2*sum2;
r=ans1/sqrt(ans2*ans3);

printf(ans1r=%f\n,ans1);
printf(ans2r=%f\n,ans2);
printf(ans3r=%f\n,ans3);
printf(r=%f\n,r);
printf(↑相関係数\n);
return r;

fclose(input1);
fclose(input2);
}


返信引用
TAKA
 TAKA
(@TAKA)
ゲスト
結合: 24年前
投稿: 117
 

データに対してどんな結果が正かわからないため判断しがたいですね・・・。
とりあえず、こんなとこが考えられますが・・・。

1.ファイル内のデータの少ない方までを計算する。(前回の参照)
2.ファイル内のデータの少ない方のデータのI・Mの初期値を1.0fとする。

こんなんでどうでしょう?

bool bFile1end, bFile2end;
bFile1end = bFile2end = false;

for (i = 0; i <= n; i++) {
/*一つ目のファイルから読み込み*/
if (bFile1end == false) {
if (fscanf(input1,%f\t%f\t%f\n,&x1[i],&y1[i],&I) == EOF) {
bFile1end = true;
I = 1.0f; // 以降1.0fとする 1.ならここでbreak;
}
}
/*二つ目のファイルから読み込み*/
if (bFile2end == false) {
if (fscanf(input2,%f\t%f\t%f\n,&x2[i],&y2[i],&M) == EOF) {
bFile2end = true;
M = 1.0f; // 以降1.0fとする 1.ならここでbreak;
}
}
if (bFile1end && bFile2end) { // 両方EOFなら終了
break;
}
sum1 += I;
sum2 += M;
sum3 += I * M;
sum4 += I * I;
sum5 += M * M;
}


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました