00001 #ifndef osl_canny_smooth_txx_
00002 #define osl_canny_smooth_txx_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "osl_canny_smooth.h"
00015 #include <vcl_cmath.h>
00016 #include <vil1/vil1_rgb.h>
00017 #include <vil1/vil1_memory_image_of.h>
00018
00019
00020 template <class T>
00021 inline float as_float(T const &v) { return float(v); }
00022
00023 VCL_DEFINE_SPECIALIZATION
00024 inline float as_float(vil1_rgb<unsigned char> const &v) { return v.grey(); }
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 template <class T>
00043 void osl_canny_smooth_rothwell(T const * const *image_in, int xsize_, int ysize_,
00044 float const *kernel_, int width_, int k_size_,
00045 float * unpro_const *smooth_)
00046 {
00047
00048 vil1_memory_image_of<float> tmp(ysize_, xsize_);
00049 tmp.fill(0);
00050
00051
00052 for (int y=0; y<ysize_; ++y)
00053 for (int x=width_; x<xsize_-width_; ++x)
00054 for (int i=0,xx=x-width_; i<k_size_; i++,xx++)
00055 tmp[x][y] += as_float(image_in[xx][y]) * kernel_[i];
00056
00057
00058 for (int y=width_; y<ysize_-width_; ++y)
00059 for (int x=0; x<xsize_; ++x)
00060 for (int i=0,yy=y-width_; i<k_size_; i++,yy++)
00061 smooth_[x][y] += tmp[x][yy]*kernel_[i];
00062 }
00063
00064
00065
00066
00067 template <class T>
00068 void osl_canny_smooth_rothwell_adaptive(T const * const *image_, int , int ,
00069 int x0, int y0, int image_size,
00070 float const *kernel_, int width_, int k_size_,
00071 float * unpro_const *dx,
00072 float * unpro_const *dy,
00073 float * unpro_const *grad)
00074 {
00075
00076 for (int j=0; j<image_size; ++j)
00077 for (int i=0; i<image_size; ++i) {
00078 dx[i][j] = 0.0;
00079 dy[i][j] = 0.0;
00080 grad[i][j] = 0.0;
00081 }
00082
00083
00084
00085
00086
00087 for (int y=width_; y<image_size-width_; ++y)
00088 for (int x=width_; x<image_size-width_; ++x)
00089 for (int i=0,j=x-width_; i<k_size_; i++,j++)
00090 dx[x][y] += as_float(image_[j+x0][y+y0])*kernel_[i];
00091
00092
00093 for (int x=width_; x<image_size-width_; ++x)
00094 for (int y=width_; y<image_size-width_; ++y)
00095 for (int i=0,j=y-width_; i<k_size_; i++,j++)
00096 dx[x][y] += as_float(image_[x+x0][j+y0])*kernel_[i];
00097
00098
00099 for (int x=width_; x<image_size-width_; ++x)
00100 for (int y=width_; y<image_size-width_; ++y)
00101 grad[x][y] = vcl_sqrt(dx[x][y]*dx[x][y] + dy[x][y]*dy[x][y]);
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 #define thePixel(b,x,y) as_float(b[x][y])
00128
00129 template <class T>
00130 void osl_canny_smooth(T const * const * image_in, int xsize_, int ysize_,
00131 float const *kernel_, int width_, float const *sub_area_,
00132 float * unpro_const * image_out)
00133 {
00134 vil1_memory_image_of<float> tmp(ysize_, xsize_);
00135 tmp.fill(0);
00136
00137
00138 for (int y=0; y<ysize_; ++y) {
00139
00140 for (int x=0; x<width_-1; ++x) {
00141 tmp[x][y] = thePixel(image_in,x,y)*kernel_[0];
00142 for (int k=1; k < width_; ++k) {
00143 if (x-k < 0)
00144 tmp[x][y] += thePixel(image_in,x+k,y)*kernel_[k];
00145 else
00146 tmp[x][y] += thePixel(image_in,x-k,y)*kernel_[k] + thePixel(image_in,x+k,y)*kernel_[k];
00147 }
00148 tmp[x][y] /= sub_area_[x+1];
00149 }
00150
00151
00152 for (int x=width_-1; x<xsize_-width_+1; ++x) {
00153 tmp[x][y] = thePixel(image_in,x,y)*kernel_[0];
00154 for (int k=1; k < width_; ++k)
00155 tmp[x][y] += thePixel(image_in,x-k,y)*kernel_[k] + thePixel(image_in,x+k,y)*kernel_[k];
00156 }
00157
00158
00159 for (int x=xsize_-width_+1; x < xsize_; ++x) {
00160 tmp[x][y] = thePixel(image_in,x,y)*kernel_[0];
00161 for (int k=1; k < width_; ++k) {
00162 if (x+k >= xsize_)
00163 tmp[x][y] += thePixel(image_in,x-k,y)*kernel_[k];
00164 else
00165 tmp[x][y] += thePixel(image_in,x-k,y)*kernel_[k] + thePixel(image_in,x+k,y)*kernel_[k];
00166 }
00167 tmp[x][y] /= sub_area_[xsize_-x];
00168 }
00169 }
00170
00171
00172
00173 for (int x=0; x < xsize_; ++x) {
00174
00175 for (int y=0; y < width_-1; ++y) {
00176 image_out[x][y] = tmp[x][y]*kernel_[0];
00177 for (int k=1; k < width_; ++k) {
00178 if (y-k < 0)
00179 image_out[x][y] += tmp[x][y+k]*kernel_[k];
00180 else
00181 image_out[x][y] += tmp[x][y-k]*kernel_[k] + tmp[x][y+k]*kernel_[k];
00182 }
00183 image_out[x][y] /= sub_area_[y+1];
00184 }
00185
00186
00187 for (int y=width_-1; y < ysize_-width_+1; ++y) {
00188 image_out[x][y] = tmp[x][y]*kernel_[0];
00189 for (int k=1; k < width_; ++k) {
00190 image_out[x][y] += tmp[x][y-k]*kernel_[k] + tmp[x][y+k]*kernel_[k];
00191 }
00192 }
00193
00194
00195 for (int y=ysize_-width_+1; y < ysize_; ++y) {
00196 image_out[x][y] = tmp[x][y]*kernel_[0];
00197 for (int k=1; k < width_; ++k) {
00198 if (y+k >= ysize_)
00199 image_out[x][y] += tmp[x][y-k]*kernel_[k];
00200 else
00201 image_out[x][y] += tmp[x][y-k]*kernel_[k] + tmp[x][y+k]*kernel_[k];
00202 }
00203 image_out[x][y] /= sub_area_[ysize_-y];
00204 }
00205 }
00206 }
00207
00208
00209
00210 #define OSL_CANNY_SMOOTH_INSTANTIATE(T) \
00211 template void osl_canny_smooth_rothwell(T const * const *image_in, int xsize_, int ysize_, \
00212 float const *kernel_, int width_, int k_size_, \
00213 float * unpro_const *smooth_); \
00214 template void osl_canny_smooth_rothwell_adaptive(T const * const *in, int xsize_, int ysize_, \
00215 int x0, int y0, int image_size, \
00216 float const *kernel_, int width_, int k_size_, \
00217 float * unpro_const *dx, float * unpro_const *dy, float * unpro_const *grad); \
00218 template void osl_canny_smooth(T const * const *image_in, int xsize_, int ysize_, \
00219 float const *kernel_, int width_, float const *sub_area_, \
00220 float * unpro_const * image_out)
00221
00222
00223 #endif // osl_canny_smooth_txx_