Lanczos3 Interpolator
-
Hallo,
hab ein problem, da ich nicht weiss ob meine Implementierung vom Lanczos Filter richtig ist. Das Lena Bild wird gescalt und ist auch nicht so pixelig wie mit einem KNN Filter, aber einen Unterschied zu Linear Interpolator sehe ich nicht wirklich. Muss es morgen schon abgeben, ist ne übung:)
Hier die Klasse:
#include <math.h> #include <stdio.h> #include <iostream> #include "ImageLanczosInterpolator.h" // Define the value of pi. #define PI 3.1415926535 /* Constructor. */ ImageLanczosInterpolator::ImageLanczosInterpolator() { // Set default window. m_SincWindow = 3; int alpha = static_cast<int>(m_SincWindow); } /* Destructor. */ ImageLanczosInterpolator::~ImageLanczosInterpolator() { } // Sinc Function double ImageLanczosInterpolator::Sinc(const double value) const { if(value == 0) return 1; return (sin(PI*value)/(PI*value)); } // Lanczos Weight double ImageLanczosInterpolator::Lanczos(const double value) const { if(((value > -alpha) && (value < alpha)) || value !=0) return (Sinc(value)*Sinc(value/m_SincWindow)); else if(value == 0) return 1; else{ return 0; } } Image::PixelType ImageLanczosInterpolator::InterpolateAtPoint( const double x, const double y ) const { // Calculate continuous index for the point. double contIndexX; double contIndexY; TransformPointToContinuousIndex( x, y, contIndexX, contIndexY ); // Check for image boundary. // In this implementation, a simple grid point discretization is used. // I.e. the pixel value is determined by the value of the upper left point of // the pixel in continuous space. Therefore, the image provides greyvalue // information for continuous indices in [0..size). Interpolating at a point // outside this region will return the value 0. if( contIndexX < 0 || contIndexX >= m_pImage->GetSizeX() || contIndexY < 0 || contIndexY >= m_pImage->GetSizeY() ) { return 0; } else { Image::PixelType outValue = 0; /* * TODO: Task 2: Implement lanczos interpolation. * * The required window size \alpha is stored in m_SincWindow and set to 3 * by default. * * The following steps have to be performed: * - Calculate the weights w(i-x) and w(j-y). Remember to set w(0) = 1 * to avoid dividing by zero. * - Normalize the weights. * - Iterate over neighbors and multiply each value with the corresponding * weights. Here, mind reflective boundary conditions. * Reflective boundary conditions: * assuming (i,j) is the current pixel location in the neighborhood of (x,y) * You can use the following code to apply reflected boundary conditions * if( i < 0 ) i = -i - 1; * else if( i >= imageSizeX ) i = 2 * imageSizeX - i - 1; * * if( j < 0 ) j = -j - 1; * else if( j >= imageSizeY ) j = 2 * imageSizeY - j - 1; * * */ double floorX, floorY, actX, actY; floorX = floor(contIndexX); floorY = floor(contIndexY); // Filter Size const double filterSizeX = static_cast<double>(m_SincWindow); const double filterSizeY = static_cast<double>(m_SincWindow); const int imageSizeX = m_pImage->GetSizeX(); const int imageSizeY = m_pImage->GetSizeY(); // Variable to accumulate weighted greyvalues. double sumWeights = 0; // Variable to accumulate greyvalues. double sumPic = 0; for(int j = floorY-filterSizeY+1;j <= floorY+filterSizeY;j++) { for(int i = floorX-filterSizeX+1;i <= floorX+filterSizeX;i++) { // Calculating Pic and Weights sumWeights += Lanczos(contIndexX-i)*Lanczos(contIndexY-j); sumPic += m_pImage->GetPixel(i,j)*Lanczos(contIndexX-i)*Lanczos(contIndexY-j); } } outValue = static_cast<Image::PixelType>(sumPic/sumWeights); return outValue; } }
-
schaut auf den ersten blick ziemlich korrekt aus. kann es sein dass du in zeile 118 und 120 -1 statt +1 meinst? aufgrund der window funktion sollte es an sich egal sein wenn du zuviel samplest, aber mit +1 ist deine ragen von -2 bis einschliesslich 3 und ich denke du meinst eher -3.
viel glueck