00001 #ifndef ImageWarp_txx_
00002 #define ImageWarp_txx_
00003
00004 #include "ImageWarp.h"
00005
00006 #include <vcl_iostream.h>
00007 #include <vnl/vnl_math.h>
00008 #include <vil1/vil1_memory_image_of.h>
00009
00010 #include <oxp/Mapping_2d_2d.h>
00011
00012
00013
00014
00015
00016 template <class PixelType>
00017 void ImageWarp<PixelType>::mean_nz_intensity(const vil1_memory_image_of<PixelType>& in,
00018 int x, int y, int window_size,
00019 typename vnl_numeric_traits<PixelType>::real_t* out,
00020 int * nnzp)
00021 {
00022
00023 PixelType const zero = vnl_numeric_traits<PixelType>::zero;
00024 PixelType total_nz = zero;
00025 int nnz = 0;
00026 if (in.in_range_window(x, y, window_size)) {
00027 for (int iy = y - window_size; iy < y + window_size; ++iy)
00028 for (int ix = x - window_size; ix < x + window_size; ++ix) {
00029 PixelType v = in(ix, iy);
00030 if (v != zero) {
00031 total_nz += v;
00032 ++nnz;
00033 }
00034 }
00035 } else {
00036 for (int iy = y - window_size; iy < y + window_size; ++iy)
00037 for (int ix = x - window_size; ix < x + window_size; ++ix)
00038 if (in.in_range(ix, iy)) {
00039 PixelType v = in(ix, iy);
00040 if (v != zero) {
00041 total_nz += v;
00042 ++nnz;
00043 }
00044 }
00045 }
00046
00047 if (nnzp)
00048 *nnzp = nnz;
00049 if (nnz > 0)
00050 *out = total_nz * (1.0 / nnz);
00051 }
00052
00053 template <class PixelType>
00054 void ImageWarp<PixelType>::gapfill(vil1_memory_image_of<PixelType>& out, int ngaps)
00055 {
00056 int w = out.width();
00057 int h = out.height();
00058
00059 int minnz = 4;
00060 while (ngaps > 0) {
00061 while (true) {
00062 vcl_cerr << "Gapfilling " << ngaps << " pixels\n";
00063 int old_ngaps = ngaps;
00064 for (int oy = 0; oy < h; ++oy)
00065 for (int ox = 0; ox < w; ++ox)
00066 if (out(ox, oy) == vnl_numeric_traits<PixelType>::zero) {
00067 int nnz;
00068 real_t tmp;
00069 mean_nz_intensity(out, ox, oy, 1, &tmp, &nnz);
00070 if (nnz >= minnz) {
00071 --ngaps;
00072 out(ox, oy) = PixelType(tmp);
00073 }
00074 }
00075 if (ngaps == old_ngaps)
00076 break;
00077 }
00078 --minnz;
00079 }
00080 }
00081
00082 template <class PixelType>
00083 void ImageWarp<PixelType>::warp(Mapping_2d_2d& map,
00084 const vil1_memory_image_of<PixelType>& in,
00085 vil1_memory_image_of<PixelType>& out)
00086 {
00087
00088 int w = in.width();
00089 int h = in.height();
00090
00091 for (int iy = 0; iy < h; ++iy)
00092 for (int ix = 0; ix < w; ++ix)
00093 {
00094
00095
00096
00097 double oxd, oyd;
00098 map.map(double(ix), double(iy), &oxd, &oyd);
00099
00100
00101 int ox = vnl_math_rnd(oxd);
00102 int oy = vnl_math_rnd(oyd);
00103
00104 if (out.in_range(ox, oy))
00105 out(ox, oy) = in(ix,iy);
00106
00107
00108 }
00109
00110 }
00111
00112 template <class PixelType>
00113 void ImageWarp<PixelType>::warp_inverse(Mapping_2d_2d& map,
00114 const vil1_memory_image_of<PixelType>&in,
00115 vil1_memory_image_of<PixelType>& out)
00116 {
00117 int w = in.width();
00118 int h = in.height();
00119
00120 int out_w = out.width();
00121 int out_h = out.height();
00122
00123 int out_offset_x = (w - out_w) / 2;
00124 int out_offset_y = (h - out_h) / 2;
00125
00126 for (int oy = 0; oy < out_h; ++oy)
00127 for (int ox = 0; ox < out_w; ++ox) {
00128
00129
00130
00131 double ixd, iyd;
00132 map.inverse_map(double(ox + out_offset_x), double(oy + out_offset_y), &ixd, &iyd);
00133
00134 #if 0
00135 switch (1) {
00136 case 1: {
00137 #endif
00138
00139 int ix = vnl_math_rnd(ixd);
00140 int iy = vnl_math_rnd(iyd);
00141 if (in.in_range(ix, iy))
00142 out(ox, oy) = in(ix,iy);
00143 else
00144 out(ox, oy) = vnl_numeric_traits<PixelType>::zero;
00145 #if 0
00146 break;
00147 }
00148 case 2: {
00149
00150 out(ox, oy) = vbl_clamp(in.bilinear(ixd, iyd), (PixelType*)0);
00151 break;
00152 }
00153 case 3: {
00154 out(ox, oy) = vbl_clamp(in.bicubic(ixd, iyd), (PixelType*)0);
00155 break;
00156 }
00157 }
00158 #endif
00159 }
00160 }
00161
00162 #undef VCL_USE_TYPENAME_ATTR
00163
00164 #endif // ImageWarp_txx_