#pragma once #include #include #include "Image2D.h" #include "BoxSizes.h" template struct BoxGaus { void boxfilter(std::vector& input, size_t w, size_t h, unsigned filterSize) { assertMsg((filterSize % 2) == 1, "filterSize must be odd"); unsigned radius = filterSize / 2; std::vector buffer(input.size()); boxBlur(input, buffer, w, h, radius); boxBlur(buffer, input, w, h, radius); } void approxGaus(Image2D& input, T sigmaX, T sigmaY, unsigned nFilt) { approxGaus(input.data(), input.width, input.height, sigmaX, sigmaY, nFilt); } void approxGaus(std::vector& input, size_t w, size_t h, T sigmaX, T sigmaY, unsigned nFilt) { BoxSizes bsX(sigmaX, nFilt); BoxSizes bsY(sigmaY, nFilt); std::vector buffer(input.size()); assertMsg((2 * bsX.wl + 1 < w) && (2 * bsX.wl + 1 < h), "Box-Filter size in X direction is too big"); assertMsg((2 * bsX.wu + 1 < w) && (2 * bsX.wu + 1 < h), "Box-Filter size in X direction is too big"); assertMsg((2 * bsY.wl + 1 < w) && (2 * bsY.wl + 1 < h), "Box-Filter size in Y direction is too big"); assertMsg((2 * bsY.wu + 1 < w) && (2 * bsY.wu + 1 < h), "Box-Filter size in Y direction is too big"); // if equal, we can save some cond's inside the loop if (bsX.m == bsY.m) { const size_t m = bsX.m; for (size_t i = 0; i < m; i++) { boxBlur(input, buffer, w, h, bsY.wl); boxBlur(buffer, input, w, h, bsX.wl); } for (size_t i = 0; i < nFilt - m; i++) { boxBlur(input, buffer, w, h, bsY.wu); boxBlur(buffer, input, w, h, bsX.wu); } } else { for (size_t i = 0; i < nFilt; i++) { boxBlur(input, buffer, w, h, (i < bsY.m ? bsY.wl : bsY.wu) ); boxBlur(buffer, input, w, h, (i < bsX.m ? bsX.wl : bsX.wu)); } } } private: void boxBlur(const std::vector &src, std::vector &dst, size_t w, size_t h, size_t r) { T iarr = (T)1.0 / (r + r + 1); for (size_t i = 0; i < w; i++) { // Init indexes size_t ti = i; size_t li = ti; size_t ri = ti + r*w; // Init values T fv = src[ti]; // first values T lv = src[ti + w*(h - 1)]; // last values T val = fv * (r + 1); // overhang over image border for (size_t j = 0; j < r; j++) { val += src[ti + j*w]; // col sum } // Überhangbereich links vom Bild for (size_t j = 0; j <= r; j++) { val += src[ri] - fv; dst[i + j*w] = val * iarr; ri += w; ti += w; } // Bildbereich for (size_t j = r + 1; j < h - r; j++) { val += src[ri] - src[li]; dst[i + j*w] = val * iarr; li += w; ri += w; ti += w; } // Überhangbereich rechts vom Bild for (size_t j = h - r; j < h; j++) { val += lv - src[li]; dst[i + j*w] = val * iarr; li += w; ti += w; } } int test = 0; } };