ref #39 smoothing is refactored
KDE smoothing algorithmisch mal geschrieben, jetzt noch testen
This commit is contained in:
127
math/boxkde/BoxGaus.h
Normal file
127
math/boxkde/BoxGaus.h
Normal file
@@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
#include "BoxSizes.h"
|
||||
|
||||
template <class T>
|
||||
struct BoxGaus
|
||||
{
|
||||
void boxfilter(std::vector<T>& input, size_t w, size_t h, unsigned filterSize)
|
||||
{
|
||||
assertMsg((filterSize % 2) == 1, "filterSize must be odd");
|
||||
|
||||
unsigned radius = filterSize / 2;
|
||||
|
||||
std::vector<T> buffer(input.size());
|
||||
boxBlur(input, buffer, w, h, radius);
|
||||
boxBlur(buffer, input, w, h, radius);
|
||||
}
|
||||
|
||||
void approxGaus(Image2D<T>& input, T sigmaX, T sigmaY, unsigned nFilt)
|
||||
{
|
||||
approxGaus(input.data(), input.width, input.height, sigmaX, sigmaY, nFilt);
|
||||
}
|
||||
|
||||
void approxGaus(std::vector<T>& input, size_t w, size_t h, T sigmaX, T sigmaY, unsigned nFilt)
|
||||
{
|
||||
BoxSizes<T> bsX(sigmaX, nFilt);
|
||||
BoxSizes<T> bsY(sigmaY, nFilt);
|
||||
std::vector<T> 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<T> &src, std::vector<T> &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
|
||||
}
|
||||
|
||||
// <20>berhangbereich links vom Bild
|
||||
for (size_t j = 0; j <= r; j++)
|
||||
{
|
||||
val += src[ri] - fv;
|
||||
dst[j + i*w] = val * iarr;
|
||||
|
||||
ri += w;
|
||||
ti += w;
|
||||
}
|
||||
|
||||
// Bildbereich
|
||||
for (size_t j = r + 1; j < h - r; j++)
|
||||
{
|
||||
val += src[ri] - src[li];
|
||||
dst[j + i*w] = val * iarr;
|
||||
|
||||
li += w;
|
||||
ri += w;
|
||||
ti += w;
|
||||
}
|
||||
|
||||
// <20>berhangbereich rechts vom Bild
|
||||
for (size_t j = h - r; j < h; j++)
|
||||
{
|
||||
val += lv - src[li];
|
||||
dst[j + i*w] = val * iarr;
|
||||
|
||||
li += w;
|
||||
ti += w;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user