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 }