写像変換3

 投稿者:しばっち  投稿日:2011年 5月21日(土)20時02分46秒
  !'写像変換(回転)

PUBLIC NUMERIC XSIZE,YSIZE
OPTION BASE 0
FILE GETNAME F$, "BMP,JPG,GIFファイル|*.BMP;*.JPG;*.GIF"
IF F$="" THEN STOP
CALL PICTURELOAD(F$,XSIZE,YSIZE)
DIM M(XSIZE,YSIZE),A(3,3),B(3,3),D(3)
ASK PIXEL ARRAY(0,0) M
LET MODE=2
LET X0=XSIZE/2
LET Y0=YSIZE/2
LET  XMAX = XSIZE - 1
LET  YMAX = YSIZE - 1
LET  XMIN = 0
LET  YMIN = 0
LET TH=40 !'回転角
LET  C = COS(TH*PI/180)
LET  S = SIN(TH*PI/180)
LET XA = INT((XMIN - X0) * C - (YMIN - Y0) * S + X0) !'回転後の座標
LET YA = INT((XMIN - X0) * S + (YMIN - Y0) * C + Y0)
LET XB = INT((XMIN - X0) * C - (YMAX - Y0) * S + X0)
LET YB = INT((XMIN - X0) * S + (YMAX - Y0) * C + Y0)
LET XC = INT((XMAX - X0) * C - (YMAX - Y0) * S + X0)
LET YC = INT((XMAX - X0) * S + (YMAX - Y0) * C + Y0)
LET XD = INT((XMAX - X0) * C - (YMIN - Y0) * S + X0)
LET YD = INT((XMAX - X0) * S + (YMIN - Y0) * C + Y0)
LET T=MIN(MIN(0,MIN(XA,XB)),MIN(XC,XD))
LET XA=XA-T
LET XB=XB-T
LET XC=XC-T
LET XD=XD-T
LET T=MIN(MIN(0,MIN(YA,YB)),MIN(YC,YD))
LET YA=YA-T
LET YB=YB-T
LET YC=YC-T
LET YD=YD-T
LET PX=(XA+XB+XC+XD)/4
LET PY=(YA+YB+YC+YD)/4
!' 変換式(共一次変換)
!'XA=A*X*Y+B*X+C*Y+D
!'YA=E*X*Y+F*X+G*Y+H

!'4元連立方程式
!'A1*X1*Y1+B1*X1+C1*Y1+D1=XA
!'A1*X2*Y2+B1*X2+C1*Y2+D1=XB
!'A1*X3*Y3+B1*X3+C1*Y3+D1=XC
!'A1*X4*Y4+B1*X4+C1*Y4+D1=XD

!'E1*X1*Y1+F1*X1+G1*Y1+H1=YA
!'E1*X2*Y2+F1*X2+G1*Y2+H1=YB
!'E1*X3*Y3+F1*X3+G1*Y3+H1=YC
!'E1*X4*Y4+F1*X4+G1*Y4+H1=YD

LET A(0,0)=XMIN*YMIN !'左上
LET A(0,1)=XMIN
LET A(0,2)=YMIN
LET A(0,3)=1
LET D(0)=XA
LET A(1,0)=XMAX*YMIN !'右上
LET A(1,1)=XMAX
LET A(1,2)=YMIN
LET A(1,3)=1
LET D(1)=XB
LET A(2,0)=XMAX*YMAX !'右下
LET A(2,1)=XMAX
LET A(2,2)=YMAX
LET A(2,3)=1
LET D(2)=XC
LET A(3,0)=XMIN*YMAX !'左下
LET A(3,1)=XMIN
LET A(3,2)=YMAX
LET A(3,3)=1
LET D(3)=XD
MAT B=INV(A)
MAT D=B*D !'方程式を解く
LET A1=D(0)
LET B1=D(1)
LET C1=D(2)
LET D1=D(3)

LET D(0)=YA
LET D(1)=YB
LET D(2)=YC
LET D(3)=YD
MAT D=B*D
LET E1=D(0)
LET F1=D(1)
LET G1=D(2)
LET H1=D(3)
LET XE = MAX(MAX(XA,XB),MAX(XC,XD))
LET YE = MAX(MAX(YA,YB),MAX(YC,YD))
CALL GINIT(XE,YE)
FOR Y = 0 TO YE
   FOR X = 0 TO XE
      CALL SOLVE (A1, B1, C1, D1-X, E1, F1, G1, H1-Y, XX, YY) !'逆変換
      !'  XX=(XA+XC-XD-XB)*S*T+(XB-XA)*S+(XD-XA)*T+XA
      !'  YY=(YA+YC-YD-YB)*S*T+(YB-YA)*S+(YD-YA)*T+YA
      !'  0<=S<=1 , 0<=T<=1
      IF XX>= 0 AND XX <= XSIZE-1 AND YY >= 0 AND YY <= YSIZE-1 THEN
         SELECT CASE MODE
         CASE 0
            CALL NEAR(XX,YY,M,RR,GG,BB)
         CASE 1
            CALL BILIEAR(XX,YY,M,RR,GG,BB)
         CASE 2
            CALL BICUBIC(XX,YY,M,RR,GG,BB)
         END SELECT
         CALL PSET(X,Y,RR,GG,BB)
      END IF
   NEXT X
NEXT Y
END

EXTERNAL  SUB SOLVE (A, B, C, D, E, F, G, H, XA, YA) !'逆変換
!'   XA,YAを求める
!'   A*XA*YA+B*XA+C*YA+D=0
!'   E*XA*YA+F*XA+G*YA+H=0

!'     XA*(A*YA+B)=-C*YA-D
!'   E*XA*YA*(A*YA+B)+F*XA*(A*YA+B)+G*YA*(A*YA+B)+H*(A*YA+B)=0
!'   E*YA*  (-C*YA-D)+F*(-C*YA-D)  +G*YA*(A*YA+B)+H*(A*YA+B)=0
!'   YA^2*(-E*C+A*G)+YA*(-E*D-F*C+G*B+A*H)+(-F*D+H*B)=0
!'   XA=(-C*YA-D)/(A*YA+B)
LET  AA = -E * C + A * G
LET  BB = -E * D - F * C + G * B + A * H
LET  CC = -F * D + H * B
LET  DD = BB * BB - 4 * AA * CC
IF DD < 0 THEN !'解なしなら負数を返す
   LET  XA = -1
   LET  YA = -1
   EXIT SUB
END IF
LET  YA =INT((-BB + SQR(DD)) / (2 * AA))
LET  XA =INT((-C*YA-D)/(A*YA+B))
IF XA >= 0 AND XA <= XSIZE-1 AND YA>=0 AND YA<=YSIZE-1 THEN EXIT SUB
LET  YA =INT((-BB - SQR(DD)) / (2 * AA))
LET  XA =INT((-C*YA-D)/(A*YA+B))
IF XA >= 0 AND XA <= XSIZE-1 AND YA>=0 AND YA<=YSIZE-1 THEN EXIT SUB
LET  XA = -1
LET  YA = -1
END SUB
 

戻る