Add convolution method to TexImage. Fixes issue 166.

pull/216/head
castano 13 years ago
parent 8c65e4c62d
commit 91e6bbe5c3

@ -283,7 +283,6 @@ void GaussianFilter::setParameters(float variance)
/// Ctor.
Kernel1::Kernel1(const Filter & f, int iscale, int samples/*= 32*/) Kernel1::Kernel1(const Filter & f, int iscale, int samples/*= 32*/)
{ {
nvDebugCheck(iscale > 1); nvDebugCheck(iscale > 1);
@ -312,13 +311,12 @@ Kernel1::Kernel1(const Filter & f, int iscale, int samples/*= 32*/)
} }
} }
/// Dtor.
Kernel1::~Kernel1() Kernel1::~Kernel1()
{ {
delete m_data; delete m_data;
} }
/// Print the kernel for debugging purposes. // Print the kernel for debugging purposes.
void Kernel1::debugPrint() void Kernel1::debugPrint()
{ {
for (int i = 0; i < m_windowSize; i++) { for (int i = 0; i < m_windowSize; i++) {
@ -328,13 +326,18 @@ void Kernel1::debugPrint()
/// Ctor.
Kernel2::Kernel2(uint ws) : m_windowSize(ws) Kernel2::Kernel2(uint ws) : m_windowSize(ws)
{ {
m_data = new float[m_windowSize * m_windowSize]; m_data = new float[m_windowSize * m_windowSize];
} }
/// Copy ctor. Kernel2::Kernel2(uint ws, const float * data) : m_windowSize(ws)
{
m_data = new float[m_windowSize * m_windowSize];
memcpy(m_data, data, sizeof(float) * m_windowSize * m_windowSize);
}
Kernel2::Kernel2(const Kernel2 & k) : m_windowSize(k.m_windowSize) Kernel2::Kernel2(const Kernel2 & k) : m_windowSize(k.m_windowSize)
{ {
m_data = new float[m_windowSize * m_windowSize]; m_data = new float[m_windowSize * m_windowSize];
@ -344,13 +347,12 @@ Kernel2::Kernel2(const Kernel2 & k) : m_windowSize(k.m_windowSize)
} }
/// Dtor.
Kernel2::~Kernel2() Kernel2::~Kernel2()
{ {
delete m_data; delete m_data;
} }
/// Normalize the filter. // Normalize the filter.
void Kernel2::normalize() void Kernel2::normalize()
{ {
float total = 0.0f; float total = 0.0f;
@ -364,7 +366,7 @@ void Kernel2::normalize()
} }
} }
/// Transpose the kernel. // Transpose the kernel.
void Kernel2::transpose() void Kernel2::transpose()
{ {
for(uint i = 0; i < m_windowSize; i++) { for(uint i = 0; i < m_windowSize; i++) {
@ -374,7 +376,7 @@ void Kernel2::transpose()
} }
} }
/// Init laplacian filter, usually used for sharpening. // Init laplacian filter, usually used for sharpening.
void Kernel2::initLaplacian() void Kernel2::initLaplacian()
{ {
nvDebugCheck(m_windowSize == 3); nvDebugCheck(m_windowSize == 3);
@ -392,7 +394,7 @@ void Kernel2::initLaplacian()
} }
/// Init simple edge detection filter. // Init simple edge detection filter.
void Kernel2::initEdgeDetection() void Kernel2::initEdgeDetection()
{ {
nvCheck(m_windowSize == 3); nvCheck(m_windowSize == 3);
@ -401,7 +403,7 @@ void Kernel2::initEdgeDetection()
m_data[6] = 0; m_data[7] = 0; m_data[8] = 0; m_data[6] = 0; m_data[7] = 0; m_data[8] = 0;
} }
/// Init sobel filter. // Init sobel filter.
void Kernel2::initSobel() void Kernel2::initSobel()
{ {
if (m_windowSize == 3) if (m_windowSize == 3)
@ -460,7 +462,7 @@ void Kernel2::initSobel()
} }
} }
/// Init prewitt filter. // Init prewitt filter.
void Kernel2::initPrewitt() void Kernel2::initPrewitt()
{ {
if (m_windowSize == 3) if (m_windowSize == 3)
@ -486,7 +488,7 @@ void Kernel2::initPrewitt()
} }
} }
/// Init blended sobel filter. // Init blended sobel filter.
void Kernel2::initBlendedSobel(const Vector4 & scale) void Kernel2::initBlendedSobel(const Vector4 & scale)
{ {
nvCheck(m_windowSize == 9); nvCheck(m_windowSize == 9);
@ -609,7 +611,7 @@ PolyphaseKernel::~PolyphaseKernel()
} }
/// Print the kernel for debugging purposes. // Print the kernel for debugging purposes.
void PolyphaseKernel::debugPrint() const void PolyphaseKernel::debugPrint() const
{ {
for (uint i = 0; i < m_length; i++) for (uint i = 0; i < m_length; i++)

@ -166,6 +166,7 @@ namespace nv
{ {
public: public:
Kernel2(uint width); Kernel2(uint width);
Kernel2(uint width, const float * data);
Kernel2(const Kernel2 & k); Kernel2(const Kernel2 & k);
~Kernel2(); ~Kernel2();

@ -943,6 +943,26 @@ FloatImage * FloatImage::resize(const Filter & filter, uint w, uint h, uint d, W
} }
void FloatImage::convolve(const Kernel2 & k, uint c, WrapMode wm)
{
AutoPtr<FloatImage> tmpImage = clone();
uint w = m_width;
uint h = m_height;
uint d = m_depth;
for (uint z = 0; z < d; z++)
{
for (uint y = 0; y < h; y++)
{
for (uint x = 0; x < w; x++)
{
pixel(c, x, y, 0) = tmpImage->applyKernelXY(&k, x, y, z, c, wm);
}
}
}
}
/// Apply 2D kernel at the given coordinates and return result. /// Apply 2D kernel at the given coordinates and return result.
float FloatImage::applyKernelXY(const Kernel2 * k, int x, int y, int z, uint c, WrapMode wm) const float FloatImage::applyKernelXY(const Kernel2 * k, int x, int y, int z, uint c, WrapMode wm) const

@ -81,6 +81,7 @@ namespace nv
NVIMAGE_API FloatImage * resize(const Filter & filter, uint w, uint h, WrapMode wm, uint alpha) const; NVIMAGE_API FloatImage * resize(const Filter & filter, uint w, uint h, WrapMode wm, uint alpha) const;
NVIMAGE_API FloatImage * resize(const Filter & filter, uint w, uint h, uint d, WrapMode wm, uint alpha) const; NVIMAGE_API FloatImage * resize(const Filter & filter, uint w, uint h, uint d, WrapMode wm, uint alpha) const;
NVIMAGE_API void convolve(const Kernel2 & k, uint c, WrapMode wm);
//NVIMAGE_API FloatImage * downSample(const Kernel1 & filter, WrapMode wm) const; //NVIMAGE_API FloatImage * downSample(const Kernel1 & filter, WrapMode wm) const;
//NVIMAGE_API FloatImage * downSample(const Kernel1 & filter, uint w, uint h, WrapMode wm) const; //NVIMAGE_API FloatImage * downSample(const Kernel1 & filter, uint w, uint h, WrapMode wm) const;

@ -1490,6 +1490,16 @@ void TexImage::abs(int channel)
} }
} }
void TexImage::convolve(int channel, int kernelSize, float * kernelData)
{
if (m->image == NULL) return;
detach();
Kernel2 k(kernelSize, kernelData);
m->image->convolve(k, channel, (FloatImage::WrapMode)m->wrapMode);
}
/* /*
void TexImage::blockLuminanceScale(float scale) void TexImage::blockLuminanceScale(float scale)
{ {

@ -471,6 +471,7 @@ namespace nvtt
NVTT_API void toLUVW(float range = 1.0f); NVTT_API void toLUVW(float range = 1.0f);
NVTT_API void fromLUVW(float range = 1.0f); NVTT_API void fromLUVW(float range = 1.0f);
NVTT_API void abs(int channel); NVTT_API void abs(int channel);
NVTT_API void convolve(int channel, int kernelSize, float * kernelData);
//NVTT_API void blockLuminanceScale(float scale); //NVTT_API void blockLuminanceScale(float scale);

Loading…
Cancel
Save