00001
00002
00003 #ifndef FILTER_H
00004 #define FILTER_H
00005
00006 #include <vector>
00007 #include <cmath>
00008 #include "image.h"
00009 #include "misc.h"
00010 #include "convolve.h"
00011 #include "imconv.h"
00012
00013 #define WIDTH 4.0
00014
00015
00016 static void normalize(std::vector<float> &mask) {
00017 int len = mask.size();
00018 float sum = 0;
00019 for (int i = 1; i < len; i++) {
00020 sum += fabs(mask[i]);
00021 }
00022 sum = 2*sum + fabs(mask[0]);
00023 for (int i = 0; i < len; i++) {
00024 mask[i] /= sum;
00025 }
00026 }
00027
00028
00029 #define MAKE_FILTER(name, fun) \
00030 static std::vector<float> make_ ## name (float sigma) { \
00031 sigma = std::max(sigma, 0.01F); \
00032 int len = (int)ceil(sigma * WIDTH) + 1; \
00033 std::vector<float> mask(len); \
00034 for (int i = 0; i < len; i++) { \
00035 mask[i] = fun; \
00036 } \
00037 return mask; \
00038 }
00039
00040 MAKE_FILTER(fgauss, exp(-0.5*square(i/sigma)));
00041
00042
00043 static image<float> *smooth(image<float> *src, float sigma) {
00044 std::vector<float> mask = make_fgauss(sigma);
00045 normalize(mask);
00046
00047 image<float> *tmp = new image<float>(src->height(), src->width(), false);
00048 image<float> *dst = new image<float>(src->width(), src->height(), false);
00049 convolve_even(src, tmp, mask);
00050 convolve_even(tmp, dst, mask);
00051
00052 delete tmp;
00053 return dst;
00054 }
00055
00056
00057 image<float> *smooth(image<uchar> *src, float sigma) {
00058 image<float> *tmp = imageUCHARtoFLOAT(src);
00059 image<float> *dst = smooth(tmp, sigma);
00060 delete tmp;
00061 return dst;
00062 }
00063
00064
00065 static image<float> *laplacian(image<float> *src) {
00066 int width = src->width();
00067 int height = src->height();
00068 image<float> *dst = new image<float>(width, height);
00069
00070 for (int y = 1; y < height-1; y++) {
00071 for (int x = 1; x < width-1; x++) {
00072 float d2x = imRef(src, x-1, y) + imRef(src, x+1, y) -
00073 2*imRef(src, x, y);
00074 float d2y = imRef(src, x, y-1) + imRef(src, x, y+1) -
00075 2*imRef(src, x, y);
00076 imRef(dst, x, y) = d2x + d2y;
00077 }
00078 }
00079 return dst;
00080 }
00081
00082 #endif