ページ 11

射影変換の係数を4個の対応点から求める

Posted: 2014年2月19日(水) 19:33
by hhfgh992
C言語で画像処理を勉強しています.
そこで,射影変換という面白い変換に出会い,画像中の4点の座標からパラメータを導出するプログラムを書いたのですが,segmential faultとエラーが出てしまい,計算結果が合っているのかどうかもわかりません.
また,経験が浅いため,プログラムのアドバイスなどありましたら,ぜひご教授お願いします.

コード:

/*ガウスの消去法を用いて射影変換の係数を4個の対応点から求める*/
/*x1,y1: 対応点1の変形前の(x,y)座標
 u1,v1: 対応点1の変形後の(x,y)座標
 x2,y2: 対応点2の変形前の(x,y)座標
 u2,v2: 対応点2の変形後の(x,y)座標
  x3,y3: 対応点3の変形前の(x,y)座標
 u3,v3: 対応点3の変形後の(x,y)座標
  x4,y4: 対応点4の変形前の(x,y)座標
 u4,v4: 対応点4の変形後の(x,y)座標
  a,b,c: X=(ax+by+c)/(gx+hy+1)
  d,e,f: Y=(dx+ey+f)/(gx+hy+1)
  g,h:                             */



#include <stdio.h>
#include <math.h>


int main()
{
	int x1,y1,x2,y2,x3,y3,x4,y4,u1,v1,u2,v2,u3,v3,u4,v4,i,j,k;
	double *a,*b,*c,*d,*e,*f,*g,*h,z;
	double m[8][9];

	printf("x1の数値を入力してください\n");
	scanf("%d",x1);
	printf("y1の数値を入力してください\n");
	scanf("%d",y1);
	printf("x2の数値を入力してください\n");
	scanf("%d",x2);
	printf("y2の数値を入力してください\n");
	scanf("%d",y2);
	printf("x3の数値を入力してください\n");
	scanf("%d",x3);
	printf("y3の数値を入力してください\n");
	scanf("%d",y3);
	printf("x4の数値を入力してください\n");
	scanf("%d",x4);
	printf("y4の数値を入力してください\n");
	scanf("%d",y4);
	printf("u1の数値を入力してください\n");
	scanf("%d",u1);
	printf("v1の数値を入力してください\n");
	scanf("%d",v1);
	printf("u2の数値を入力してください\n");
	scanf("%d",u2);
	printf("v2の数値を入力してください\n");
	scanf("%d",v2);
	printf("u3の数値を入力してください\n");
	scanf("%d",u3);
	printf("v3の数値を入力してください\n");
	scanf("%d",v3);
	printf("u4の数値を入力してください\n");
	scanf("%d",u4);
	printf("v4の数値を入力してください\n");
	scanf("%d",v4);
	printf("x1=%d\ny1=%d\nx2=%d\ny2=%d\nx3=%d\ny3=%d\nx4=%d\ny4=%d\nu1=%d\nv1=%d\nu2=%d\nv2=%d\nu3=%d\nv3=%d\nu4=%d\nv4=%d\n",x1,y1,x2,y2,x3,y3,x4,y4,u1,v1,u2,v2,u3,v3,u4,v4);
	

	m[0][0]=x1;     	m[0][1]=y1;     	m[0][2]=1;
	m[0][3]=0;      	m[0][4]=0;      	m[0][5]=0;
	m[0][6]=-x1*u1; 	m[0][7]=-y1*u1; 	m[0][8]=u1;
	m[1][0]=0;      	m[1][1]=0;      	m[1][2]=0;
	m[1][3]=x1;    	m[1][4]=y1;     	m[1][5]=1;
	m[1][6]=-x1*v1;	m[1][7]=-y1*v1; 	m[1][8]=v1;
	m[2][0]=x2;      	m[2][1]=y2;      	m[2][2]=1;
	m[2][3]=0;    	m[2][4]=0;     	m[2][5]=0;
	m[2][6]=-x2*u2;	m[2][7]=-y2*u2; 	m[2][8]=u2;
	m[3][0]=0;      	m[3][1]=0;      	m[3][2]=0;
	m[3][3]=x2;    	m[3][4]=y2;     	m[3][5]=1;
	m[3][6]=-x2*v2;	m[3][7]=-y2*v2; 	m[3][8]=v2;
	m[4][0]=x3;      	m[4][1]=y3;      	m[4][2]=1;
	m[4][3]=0;	    	m[4][4]=0;     	m[4][5]=0;
	m[4][6]=-x3*u3;	m[4][7]=-y3*u3; 	m[4][8]=u3;
	m[5][0]=0;      	m[5][1]=0;      	m[5][2]=0;
	m[5][3]=x3;    	m[5][4]=y3;     	m[5][5]=1;
	m[5][6]=-x3*v3;	m[5][7]=-y3*v3; 	m[5][8]=v3;
	m[6][0]=x4;      	m[6][1]=0;      	m[6][2]=0;
	m[6][3]=x1;    	m[6][4]=y1;     	m[6][5]=1;
	m[6][6]=-x1*v1;	m[6][7]=-y1*v1; 	m[6][8]=v1;
	m[7][0]=0;      	m[7][1]=0;      	m[7][2]=0;
	m[7][3]=x4;    	m[7][4]=y1;     	m[7][5]=1;
	m[7][6]=-x4*v4;	m[7][7]=-y4*v4; 	m[7][8]=v4;

	for (i = 0; i < 8; i++){
		for (j = 0; j < 8; j++){
  	            printf("%+fx%d ", m[i][j], j + 1);
  	            printf("= %+f\n", m[i][8]);
		}
         }

	/*前進消去*/
	 for (k = 0; k < 8 -1; k++){
               for (i = k + 1; i < 8; i++){
                    z = m[i][k] / m[k][k];
                      for (j = k + 1; j <= 8; j++){
                          m[i][j] -= m[k][j] * z;
		 	}
                 }
          }

	/*後退代入*/
	for (i = 8 - 1; i >= 0; i--){
             z = m[i][8];
              for (j = i + 1; j < 8; j++){
                 z -= m[i][j] * m[j][8];
		 m[i][8] = z / m[i][i];
		}
         }
	
	/*結果表示*/
	for (k = 0; k < 8; k++){
              printf("x%d= %f\n", m[k][8]);
			 /*x1=a
				x2=b
				x3=c
				x4=d
				x5=e
				x6=f
				x7=g
				x8=h*/
	}
	return 0;
}

Re: 射影変換の係数を4個の対応点から求める

Posted: 2014年2月19日(水) 22:09
by kiuri
とりあえずscanfの使い方が違います。
scanf("%d",x1);ではなくscanf("%d",&x1);です。
それから最後のprintf("x%d= %f\n", m[k][8]);はprintf("x%d= %f\n", k, m[k][8]);の間違いでしょう。

内容については私は射影変換をよく知らないので他の方にお任せします。

Re: 射影変換の係数を4個の対応点から求める

Posted: 2014年2月19日(水) 22:12
by みけCAT
とりあえず、インデントを整えることをおすすめします。

Re: 射影変換の係数を4個の対応点から求める

Posted: 2014年2月20日(木) 11:54
by hhfgh992
おはようございます.
昨日は,回答ありがとうございました.
みなさんのご指摘に従い,デバッグしたところ動くようになったのですが,最後の結果表示の際に,全ての結果がX=nan と表示されました.
原因が分からず困っていますので,どこがおかしいのかご教授お願いします.

コード:

/*ガウスの消去法を用いて射影変換の係数を4個の対応点から求める*/
/*x1,y1: 対応点1の変形前の(x,y)座標
 u1,v1: 対応点1の変形後の(x,y)座標
 x2,y2: 対応点2の変形前の(x,y)座標
 u2,v2: 対応点2の変形後の(x,y)座標
  x3,y3: 対応点3の変形前の(x,y)座標
 u3,v3: 対応点3の変形後の(x,y)座標
  x4,y4: 対応点4の変形前の(x,y)座標
 u4,v4: 対応点4の変形後の(x,y)座標
  a,b,c: X=(ax+by+c)/(gx+hy+1)
  d,e,f: Y=(dx+ey+f)/(gx+hy+1)
  g,h:                             */



#include <stdio.h>
#include <math.h>


int main()
{
	int x1,y1,x2,y2,x3,y3,x4,y4,u1,v1,u2,v2,u3,v3,u4,v4,i,j,k;
	double *a,*b,*c,*d,*e,*f,*g,*h,z;
	double m[8][9];

	printf("x1の数値を入力してください\n");
	scanf("%d",&x1);
	printf("y1の数値を入力してください\n");
	scanf("%d",&y1);
	printf("x2の数値を入力してください\n");
	scanf("%d",&x2);
	printf("y2の数値を入力してください\n");
	scanf("%d",&y2);
	printf("x3の数値を入力してください\n");
	scanf("%d",&x3);
	printf("y3の数値を入力してください\n");
	scanf("%d",&y3);
	printf("x4の数値を入力してください\n");
	scanf("%d",&x4);
	printf("y4の数値を入力してください\n");
	scanf("%d",&y4);
	printf("u1の数値を入力してください\n");
	scanf("%d",&u1);
	printf("v1の数値を入力してください\n");
	scanf("%d",&v1);
	printf("u2の数値を入力してください\n");
	scanf("%d",&u2);
	printf("v2の数値を入力してください\n");
	scanf("%d",&v2);
	printf("u3の数値を入力してください\n");
	scanf("%d",&u3);
	printf("v3の数値を入力してください\n");
	scanf("%d",&v3);
	printf("u4の数値を入力してください\n");
	scanf("%d",&u4);
	printf("v4の数値を入力してください\n");
	scanf("%d",&v4);
	printf("x1=%d\ny1=%d\nx2=%d\ny2=%d\nx3=%d\ny3=%d\nx4=%d\ny4=%d\nu1=%d\nv1=%d\nu2=%d\nv2=%d\nu3=%d\nv3=%d\nu4=%d\nv4=%d\n",x1,y1,x2,y2,x3,y3,x4,y4,u1,v1,u2,v2,u3,v3,u4,v4);
	

	m[0][0]=x1;     	m[0][1]=y1;     	m[0][2]=1;
	m[0][3]=0;      	m[0][4]=0;      	m[0][5]=0;
	m[0][6]=-x1*u1; 	m[0][7]=-y1*u1; 	m[0][8]=u1;
	m[1][0]=0;      	m[1][1]=0;      	m[1][2]=0;
	m[1][3]=x1;    	  m[1][4]=y1;     	m[1][5]=1;
	m[1][6]=-x1*v1;	  m[1][7]=-y1*v1; 	m[1][8]=v1;
	m[2][0]=x2;      	m[2][1]=y2;      	m[2][2]=1;
	m[2][3]=0;    		m[2][4]=0;     	m[2][5]=0;
	m[2][6]=-x2*u2;	m[2][7]=-y2*u2; 	m[2][8]=u2;
	m[3][0]=0;      	m[3][1]=0;      	m[3][2]=0;
	m[3][3]=x2;    	m[3][4]=y2;     	m[3][5]=1;
	m[3][6]=-x2*v2;	m[3][7]=-y2*v2; 	m[3][8]=v2;
	m[4][0]=x3;      	m[4][1]=y3;      	m[4][2]=1;
	m[4][3]=0;	    	m[4][4]=0;     	m[4][5]=0;
	m[4][6]=-x3*u3;	m[4][7]=-y3*u3; 	m[4][8]=u3;
	m[5][0]=0;      	m[5][1]=0;      	m[5][2]=0;
	m[5][3]=x3;    	m[5][4]=y3;     	m[5][5]=1;
	m[5][6]=-x3*v3;	m[5][7]=-y3*v3; 	m[5][8]=v3;
	m[6][0]=x4;      	m[6][1]=0;      	m[6][2]=0;
	m[6][3]=x1;    	m[6][4]=y1;     	m[6][5]=1;
	m[6][6]=-x1*v1;	m[6][7]=-y1*v1; 	m[6][8]=v1;
	m[7][0]=0;      	m[7][1]=0;      	m[7][2]=0;
	m[7][3]=x4;    	m[7][4]=y1;     	m[7][5]=1;
	m[7][6]=-x4*v4;	m[7][7]=-y4*v4; 	m[7][8]=v4;

	for (i = 0; i < 8; i++){
		for (j = 0; j < 8; j++){
			printf("%+fx%d ", m[i][j], j + 1);
			printf("= %+f\n", m[i][8]);
		}
	}

	/*前進消去*/
	for (k = 0; k < 8 -1; k++){
		for (i = k + 1; i < 8; i++){
			z = m[i][k] / m[k][k];
				for (j = k + 1; j <= 8; j++){
					m[i][j] -= m[k][j] * z;
				}
		}
    }

	/*後退代入*/
	for (i = 8 - 1; i >= 0; i--){
		z = m[i][8];
			for (j = i + 1; j < 8; j++){
				z -= m[i][j] * m[j][8];
				m[i][8] = z / m[i][i];
			}
   }
	
	/*結果表示*/
	for (k = 0; k < 8; k++){
		printf("x%d= %f\n",k, m[k][8]);
			 /*x1=a
				x2=b
				x3=c
				x4=d
				x5=e
				x6=f
				x7=g
				x8=h*/
	}
	return 0;
}