Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
vp_warp.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #include "vp_global.h"
00032 
00033 
00034 float VPBilirpWeight[WARP_WEIGHT_ENTRIES][WARP_WEIGHT_ENTRIES][4];
00035 static int BilirpWeightsReady = 0;      
00036 
00037 static void OrderCoords ANSI_ARGS((double coords[4][2], double lft[3][2],
00038     double rgt[3][2]));
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 void
00047 VPComputeWarpTables()
00048 {
00049     float *wptr;        
00050 
00051     int x, y;
00052     double in_x, in_y;
00053 
00054     if (BilirpWeightsReady)
00055         return;
00056 
00057 #ifdef MEMSPY
00058     bin_init(BinNumber(__LINE__, __FILE__, "VPBilirpWeight"), -1, -1,
00059              VPBilirpWeight, sizeof(VPBilirpWeight), "VPBilirpWeight");
00060 #endif
00061 
00062     wptr = &VPBilirpWeight[0][0][0];
00063     for (y = 0; y < WARP_WEIGHT_ENTRIES; y++) {
00064         in_y = (double)y / (WARP_WEIGHT_ENTRIES-1);
00065         for (x = 0; x < WARP_WEIGHT_ENTRIES; x++) {
00066             in_x = (double)x / (WARP_WEIGHT_ENTRIES-1);
00067             *wptr++ = (1. - in_x)*(1. - in_y);
00068             *wptr++ = in_x * (1. - in_y);
00069             *wptr++ = (1. - in_x) * in_y;
00070             *wptr++ = 1. - wptr[-1] - wptr[-2] - wptr[-3];
00071         }
00072     }
00073 
00074     BilirpWeightsReady = 1;
00075 }
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 void
00094 VPAffineImageOverlap(in_width, in_height, out_width, out_height,
00095                      warp_matrix, filter_width, full_overlap, part_overlap)
00096 int in_width, in_height;        
00097 int out_width, out_height;      
00098 vpMatrix3 warp_matrix;          
00099 
00100 double filter_width;            
00101 
00102 Trapezoid full_overlap[9]; 
00103 
00104 Trapezoid part_overlap[9]; 
00105 
00106 {
00107     double int_lft[3][2];       
00108 
00109 
00110     double int_rgt[3][2];       
00111     double ext_lft[3][2];       
00112     double ext_rgt[3][2];       
00113     double coords[4][2];
00114     double inset;
00115     int ilft, irgt, elft, ergt;
00116     int region;
00117     int lasty, nexty, y;
00118 
00119     
00120 
00121     inset = -1.0 + filter_width / 2.0 + 1.0e-5;
00122     coords[0][0] = warp_matrix[0][0] * inset +
00123                    warp_matrix[0][1] * inset + 
00124                    warp_matrix[0][2];
00125     coords[0][1] = warp_matrix[1][0] * inset +
00126                    warp_matrix[1][1] * inset + 
00127                    warp_matrix[1][2];
00128     coords[1][0] = warp_matrix[0][0] * (in_width - 1 - inset) +
00129                    warp_matrix[0][1] * inset + 
00130                    warp_matrix[0][2];
00131     coords[1][1] = warp_matrix[1][0] * (in_width - 1 - inset) +
00132                    warp_matrix[1][1] * inset + 
00133                    warp_matrix[1][2];
00134     coords[2][0] = warp_matrix[0][0] * (in_width - 1 - inset) +
00135                    warp_matrix[0][1] * (in_height - 1 - inset) + 
00136                    warp_matrix[0][2];
00137     coords[2][1] = warp_matrix[1][0] * (in_width - 1 - inset) +
00138                    warp_matrix[1][1] * (in_height - 1 - inset) + 
00139                    warp_matrix[1][2];
00140     coords[3][0] = warp_matrix[0][0] * inset +
00141                    warp_matrix[0][1] * (in_height - 1 - inset) + 
00142                    warp_matrix[0][2];
00143     coords[3][1] = warp_matrix[1][0] * inset +
00144                    warp_matrix[1][1] * (in_height - 1 - inset) + 
00145                    warp_matrix[1][2];
00146     OrderCoords(coords, int_lft, int_rgt);
00147 
00148     
00149 
00150     inset = -filter_width / 2.0;
00151     coords[0][0] = warp_matrix[0][0] * inset +
00152                    warp_matrix[0][1] * inset + 
00153                    warp_matrix[0][2];
00154     coords[0][1] = warp_matrix[1][0] * inset +
00155                    warp_matrix[1][1] * inset + 
00156                    warp_matrix[1][2];
00157     coords[1][0] = warp_matrix[0][0] * (in_width - 1 - inset) +
00158                    warp_matrix[0][1] * inset + 
00159                    warp_matrix[0][2];
00160     coords[1][1] = warp_matrix[1][0] * (in_width - 1 - inset) +
00161                    warp_matrix[1][1] * inset + 
00162                    warp_matrix[1][2];
00163     coords[2][0] = warp_matrix[0][0] * (in_width - 1 - inset) +
00164                    warp_matrix[0][1] * (in_height - 1 - inset) + 
00165                    warp_matrix[0][2];
00166     coords[2][1] = warp_matrix[1][0] * (in_width - 1 - inset) +
00167                    warp_matrix[1][1] * (in_height - 1 - inset) + 
00168                    warp_matrix[1][2];
00169     coords[3][0] = warp_matrix[0][0] * inset +
00170                    warp_matrix[0][1] * (in_height - 1 - inset) + 
00171                    warp_matrix[0][2];
00172     coords[3][1] = warp_matrix[1][0] * inset +
00173                    warp_matrix[1][1] * (in_height - 1 - inset) + 
00174                    warp_matrix[1][2];
00175     OrderCoords(coords, ext_lft, ext_rgt);
00176 
00177     for (ilft = 0; ilft < 3 && int_lft[ilft][1] <= 0.; ilft++);
00178     for (irgt = 0; irgt < 3 && int_rgt[irgt][1] <= 0.; irgt++);
00179     for (elft = 0; elft < 3 && ext_lft[elft][1] <= 0.; elft++);
00180     for (ergt = 0; ergt < 3 && ext_rgt[ergt][1] <= 0.; ergt++);
00181     region = 0;
00182     lasty = -1;
00183     while (lasty < out_height-1) {
00184         ASSERT(region < 9);
00185 
00186         
00187         nexty = out_height - 1;
00188         if (ilft < 3) {
00189             y = (int)floor(int_lft[ilft][1]);
00190             if (nexty > y)
00191                 nexty = y;
00192         }
00193         if (irgt < 3) {
00194             y = (int)floor(int_rgt[irgt][1]);
00195             if (nexty > y)
00196                 nexty = y;
00197         }
00198         if (elft < 3) {
00199             y = (int)floor(ext_lft[elft][1]);
00200             if (nexty > y)
00201                 nexty = y;
00202         }
00203         if (ergt < 3) {
00204             y = (int)floor(ext_rgt[ergt][1]);
00205             if (nexty > y)
00206                 nexty = y;
00207         }
00208         ASSERT((ilft == 0 && (int)floor(int_lft[0][1]) >= nexty) ||
00209                (ilft == 3 && (int)floor(int_lft[2][1]) <= lasty) ||
00210                (((int)floor(int_lft[ilft-1][1]) <= lasty || lasty == -1)
00211                 && (int)floor(int_lft[ilft][1]) >= nexty));
00212         ASSERT((irgt == 0 && (int)floor(int_rgt[0][1]) >= nexty) ||
00213                (irgt == 3 && (int)floor(int_rgt[2][1]) <= lasty) ||
00214                (((int)floor(int_rgt[irgt-1][1]) <= lasty || lasty == -1)
00215                 && (int)floor(int_rgt[irgt][1]) >= nexty));
00216         ASSERT((elft == 0 && (int)floor(ext_lft[0][1]) >= nexty) ||
00217                (elft == 3 && (int)floor(ext_lft[2][1]) <= lasty) ||
00218                (((int)floor(ext_lft[elft-1][1]) <= lasty || lasty == -1)
00219                 && (int)floor(ext_lft[elft][1]) >= nexty));
00220         ASSERT((ergt == 0 && (int)floor(ext_rgt[0][1]) >= nexty) ||
00221                (ergt == 3 && (int)floor(ext_rgt[2][1]) <= lasty) ||
00222                (((int)floor(ext_rgt[ergt-1][1]) <= lasty || lasty == -1)
00223                 && (int)floor(ext_rgt[ergt][1]) >= nexty));
00224         full_overlap[region].miny = lasty + 1;
00225         full_overlap[region].maxy = nexty;
00226         part_overlap[region].miny = lasty + 1;
00227         part_overlap[region].maxy = nexty;
00228         if (ilft == 0 || ilft == 3) {
00229             
00230             full_overlap[region].x_top_lft = 0;
00231             full_overlap[region].x_top_rgt = -1;
00232             full_overlap[region].x_incr_lft = 0;
00233             full_overlap[region].x_incr_rgt = 0;
00234         } else {
00235             full_overlap[region].x_incr_lft = 
00236                 (int_lft[ilft][0] - int_lft[ilft-1][0]) /
00237                 (int_lft[ilft][1] - int_lft[ilft-1][1]);
00238             full_overlap[region].x_top_lft =
00239                 int_lft[ilft-1][0] + (lasty+1 - int_lft[ilft-1][1]) *
00240                 full_overlap[region].x_incr_lft;
00241             full_overlap[region].x_incr_rgt = 
00242                 (int_rgt[irgt][0] - int_rgt[irgt-1][0]) /
00243                 (int_rgt[irgt][1] - int_rgt[irgt-1][1]);
00244             full_overlap[region].x_top_rgt =
00245                 int_rgt[irgt-1][0] + (lasty+1 - int_rgt[irgt-1][1]) *
00246                 full_overlap[region].x_incr_rgt;
00247         }
00248         if (elft == 0 || elft == 3) {
00249             
00250             part_overlap[region].x_top_lft = 0;
00251             part_overlap[region].x_top_rgt = -1;
00252             part_overlap[region].x_incr_lft = 0;
00253             part_overlap[region].x_incr_rgt = 0;
00254         } else {
00255             part_overlap[region].x_incr_lft = 
00256                 (ext_lft[elft][0] - ext_lft[elft-1][0]) /
00257                 (ext_lft[elft][1] - ext_lft[elft-1][1]);
00258             part_overlap[region].x_top_lft =
00259                 ext_lft[elft-1][0] + (lasty+1 - ext_lft[elft-1][1]) *
00260                 part_overlap[region].x_incr_lft;
00261             part_overlap[region].x_incr_rgt = 
00262                 (ext_rgt[ergt][0] - ext_rgt[ergt-1][0]) /
00263                 (ext_rgt[ergt][1] - ext_rgt[ergt-1][1]);
00264             part_overlap[region].x_top_rgt =
00265                 ext_rgt[ergt-1][0] + (lasty+1 - ext_rgt[ergt-1][1]) *
00266                 part_overlap[region].x_incr_rgt;
00267         }
00268         ASSERT(!(full_overlap[region].x_top_lft <= 
00269                  full_overlap[region].x_top_rgt &&
00270                  part_overlap[region].x_top_lft >
00271                  part_overlap[region].x_top_rgt));
00272         for (; ilft < 3 && (int)floor(int_lft[ilft][1]) <= nexty; ilft++);
00273         for (; irgt < 3 && (int)floor(int_rgt[irgt][1]) <= nexty; irgt++);
00274         for (; elft < 3 && (int)floor(ext_lft[elft][1]) <= nexty; elft++);
00275         for (; ergt < 3 && (int)floor(ext_rgt[ergt][1]) <= nexty; ergt++);
00276         region++;
00277         lasty = nexty;
00278     }
00279     for (; region < 9; region++) {
00280         full_overlap[region].miny = out_height;
00281         full_overlap[region].maxy = out_height;
00282         part_overlap[region].miny = out_height;
00283         part_overlap[region].maxy = out_height;
00284         full_overlap[region].x_top_lft = 0;
00285         full_overlap[region].x_top_rgt = -1;
00286         full_overlap[region].x_incr_lft = 0;
00287         full_overlap[region].x_incr_rgt = 0;
00288         part_overlap[region].x_top_lft = 0;
00289         part_overlap[region].x_top_rgt = -1;
00290         part_overlap[region].x_incr_lft = 0;
00291         part_overlap[region].x_incr_rgt = 0;
00292     }
00293 
00294 #ifdef DEBUG_OVERLAP
00295     for (region = 0; region < 9; region++) {
00296         printf("region %d: y = %d to %d, [%d+%g [%d+%g %d+%g] %d+%g]\n",
00297                region,
00298                full_overlap[region].miny,
00299                full_overlap[region].maxy,
00300                (int)part_overlap[region].x_top_lft,
00301                part_overlap[region].x_incr_lft,
00302                (int)full_overlap[region].x_top_lft,
00303                full_overlap[region].x_incr_lft,
00304                (int)full_overlap[region].x_top_rgt,
00305                full_overlap[region].x_incr_rgt,
00306                (int)part_overlap[region].x_top_rgt,
00307                part_overlap[region].x_incr_rgt);
00308     }
00309 #endif
00310 }
00311 
00312 
00313 
00314 
00315 
00316 
00317 
00318 static void
00319 OrderCoords(coords, lft, rgt)
00320 double coords[4][2];    
00321 double lft[3][2];       
00322 double rgt[3][2];
00323 {
00324     int index;
00325     double swap_buf;
00326     double sorted_coords[4][2];
00327     double xmid;
00328 
00329     
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339     
00340     index = 0;
00341     if (coords[1][1] < coords[index][1] ||
00342         (coords[1][1] == coords[index][1] && coords[1][0] < coords[index][0]))
00343         index = 1;
00344     if (coords[2][1] < coords[index][1] ||
00345         (coords[2][1] == coords[index][1] && coords[2][0] < coords[index][0]))
00346         index = 2;
00347     if (coords[3][1] < coords[index][1] ||
00348         (coords[3][1] == coords[index][1] && coords[3][0] < coords[index][0]))
00349         index = 3;
00350     sorted_coords[0][0] = coords[index][0];
00351     sorted_coords[0][1] = coords[index][1];
00352 
00353     
00354     sorted_coords[2][0] = coords[(index+2)%4][0];
00355     sorted_coords[2][1] = coords[(index+2)%4][1];
00356 
00357     
00358 
00359 
00360     index = (index + 1) % 4;
00361     if (fabs(sorted_coords[0][1] - sorted_coords[2][1]) < VP_EPS) {
00362         
00363         lft[0][0] = sorted_coords[0][0];
00364         lft[0][1] = sorted_coords[0][1];
00365         lft[1][0] = sorted_coords[0][0];
00366         lft[1][1] = sorted_coords[0][1];
00367         lft[2][0] = sorted_coords[0][0];
00368         lft[2][1] = sorted_coords[0][1];
00369         rgt[0][0] = sorted_coords[2][0];
00370         rgt[0][1] = sorted_coords[2][1];
00371         rgt[1][0] = sorted_coords[2][0];
00372         rgt[1][1] = sorted_coords[2][1];
00373         rgt[2][0] = sorted_coords[2][0];
00374         rgt[2][1] = sorted_coords[2][1];
00375         return;
00376     }
00377     xmid = sorted_coords[0][0] + (coords[index][1] - sorted_coords[0][1]) *
00378            (sorted_coords[2][0] - sorted_coords[0][0]) /
00379            (sorted_coords[2][1] - sorted_coords[0][1]);
00380     if (coords[index][0] < xmid) {
00381         sorted_coords[1][0] = coords[index][0];
00382         sorted_coords[1][1] = coords[index][1];
00383         sorted_coords[3][0] = coords[(index+2)%4][0];
00384         sorted_coords[3][1] = coords[(index+2)%4][1];
00385     } else {
00386         sorted_coords[1][0] = coords[(index+2)%4][0];
00387         sorted_coords[1][1] = coords[(index+2)%4][1];
00388         sorted_coords[3][0] = coords[index][0];
00389         sorted_coords[3][1] = coords[index][1];
00390     }
00391 
00392     
00393     lft[0][0] = sorted_coords[0][0];
00394     lft[0][1] = sorted_coords[0][1];
00395     lft[1][0] = sorted_coords[1][0];
00396     lft[1][1] = sorted_coords[1][1];
00397     if (sorted_coords[1][1] == sorted_coords[2][1]) {
00398         lft[2][0] = sorted_coords[1][0];
00399         lft[2][1] = sorted_coords[1][1];
00400     } else {
00401         lft[2][0] = sorted_coords[2][0];
00402         lft[2][1] = sorted_coords[2][1];
00403     }
00404     if (sorted_coords[0][1] == sorted_coords[3][1]) {
00405         rgt[0][0] = sorted_coords[3][0];
00406         rgt[0][1] = sorted_coords[3][1];
00407         rgt[1][0] = sorted_coords[2][0];
00408         rgt[1][1] = sorted_coords[2][1];
00409         rgt[2][0] = sorted_coords[2][0];
00410         rgt[2][1] = sorted_coords[2][1];
00411     } else {
00412         rgt[0][0] = sorted_coords[0][0];
00413         rgt[0][1] = sorted_coords[0][1];
00414         rgt[1][0] = sorted_coords[3][0];
00415         rgt[1][1] = sorted_coords[3][1];
00416         rgt[2][0] = sorted_coords[2][0];
00417         rgt[2][1] = sorted_coords[2][1];
00418     }
00419 }