00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "distortion.h"
00023
00024 #include <stdio.h>
00025
00026 DistortParams *DistortParams::load(const char *file)
00027 {
00028 if (file==0) return 0;
00029
00030 FILE *f=fopen(file,"r");
00031 if (!f) {
00032 perror(file);
00033 return 0;
00034 }
00035
00036 DistortParams *r = new DistortParams();
00037
00038 int fields = fscanf(f,"%f%f%f%f%f%f%f%f",
00039 &r->fx, &r->fy, &r->cx, &r->cy,
00040 r->k, r->k+1, r->p, r->p+1);
00041 fclose(f);
00042
00043 if (fields != 8) {
00044 fprintf(stderr,"%s: can't read calibration values.\n", file);
00045 delete r;
00046 return 0;
00047 }
00048 return r;
00049 }
00050
00051 void distort(const float x, const float y, float distorted[2], const DistortParams &p)
00052 {
00053 float r2 = x*x + y*y;
00054 float d = 1+ p.k[0]*r2 + p.k[1]*r2*r2;
00055 float xy= x*y;
00056 distorted[0] = p.fx*(x * d + 2* p.p[0] *xy + p.p[1]*(r2+2*x*x)) + p.cx;
00057 distorted[1] = p.fy*(y * d + 2* p.p[1] *xy + p.p[0]*(r2+2*y*y)) + p.cy;
00058 }
00059
00060 void undistort(keypoint *kpt, const DistortParams &p)
00061 {
00062 float uv[2];
00063 undistort(kpt->fr_u(), kpt->fr_v(), uv, p);
00064 kpt->u_undist = uv[0];
00065 kpt->v_undist = uv[1];
00066 }
00067
00068 void undistort(const float _u, const float _v, float xy[2], const DistortParams &p)
00069 {
00070
00071
00072 float u = (_u-p.cx)/p.fx;
00073 float v = (_v-p.cy)/p.fy;
00074
00075
00076 float x = u;
00077 float y = v;
00078
00079
00080 for (int i=0; i<5; i++) {
00081
00082 float t1 = x*x;
00083 float t2 = p.k[0]*t1;
00084 float t3 = y*y;
00085 float t4 = p.k[0]*t3;
00086 float t6 = t1*t1;
00087 float t7 = p.k[1]*t6;
00088 float t8 = p.k[1]*t1;
00089 float t9 = t8*t3;
00090 float t10 = 6.0f*t9;
00091 float t11 = t3*t3;
00092 float t12 = p.k[1]*t11;
00093 float t14 = p.p[1]*x;
00094 float t16 = p.p[0]*y;
00095 float t21 = t1*x;
00096 float t25 = p.k[1]*p.k[1];
00097 float t27 = t11*t3;
00098 float t30 = t3*y;
00099 float t38 = t6*t1;
00100 float t62 = 1.0f+4.0f*t4+4.0f*t2+12.0f*p.k[0]*t21*p.p[1]+20.0f*t25*t1*t27+12.0f*p.k[0]*t30*
00101 p.p[0]+16.0f*p.k[1]*t11*y*p.p[0]+20.0f*t25*t38*t3+12.0f*t4*t14+16.0f*t7*t16+32.0f*p.k[1]*t21
00102 *t3*p.p[1]+32.0f*t8*t30*p.p[0]+16.0f*t12*t14+32.0f*t16*t14+12.0f*t9+30.0f*t25*t6*t11+6.0f
00103 *t12;
00104 float t65 = p.k[0]*p.k[0];
00105 float t70 = t6*t6;
00106 float t73 = t11*t11;
00107 float t76 = p.p[0]*p.p[0];
00108 float t81 = p.p[1]*p.p[1];
00109 float t108 = 8.0f*t14+8.0f*t16+3.0f*t65*t6+3.0f*t65*t11+5.0f*t25*t70+5.0f*t25*t73+
00110 12.0f*t76*t3-4.0f*t76*t1-4.0f*t81*t3+16.0f*p.k[1]*t6*x*p.p[1]+8.0f*p.k[0]*t27*p.k[1]
00111 +8.0f*p.k[0]*t38*p.k[1]+6.0f*t65*t1*t3+6.0f*t7+24.0f*t2*t12+12.0f*t81*t1+24.0f*p.k[0]*t6*p.k[1]*t3+
00112 12.0f*t2*t16;
00113 float t110 = 1.0f/(t62+t108);
00114 float t112 = t1+t3;
00115 float t114 = t112*t112;
00116 float t116 = 1.0f+p.k[0]*t112+p.k[1]*t114;
00117 float t118 = p.p[0]*x;
00118 float t124 = u-x*t116-2.0f*t118*y-p.p[1]*(3.0f*t1+t3);
00119 float t136 = (x*p.k[0]*y+2.0f*p.k[1]*y*t21+2.0f*x*p.k[1]*t30+t118+p.p[1]*y)*t110;
00120 float t143 = v-y*t116-2.0f*t14*y-p.p[0]*(t1+3.0f*t3);
00121 float dx = (1.0f+t2+3.0f*t4+t7+t10+5.0f*t12+2.0f*t14+6.0f*t16)*t110*t124-2.0f*
00122 t136*t143;
00123 float dy = -2.0f*t136*t124+(1.0f+3.0f*t2+t4+5.0f*t7+t10+t12+2.0f*t16+6.0f*t14)*
00124 t110*t143;
00125 x += dx;
00126 y += dy;
00127 if ((dx*dx+dy*dy)<(.01*.01)) break;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 xy[0] = x;
00142 xy[1] = y;
00143 }
00144