|
This is an old course web from 2008 |
Old 2008 Course Web: Main / UpsamplingExamples of UpsamplingHere are examples of upsampling with various reconstruction filters. I used my example solution to the Imaging Programming Assignment. Notice how the best filters for the checkboard example, aren't necessarily the best for a more natural image - in particular, the "sharper" filters (like Cat-Rom and Lanczos) are too sharp for the checkboard (they ring), but they produce much sharper results for the natural image. Synthetic ExampleThis is a very tiny example (24 pixels square) of a checkerboard (a bad case - natural images don't have this much high frequencies). The colors in the main parts are not black and white (they are gray) so the ringing doesn't "overflow" the 0-255 range. I have upsampled by a factor of 8.
This time scaled up by 3 - the original is pretty small. Natural Example
Here are the equations for the various filters. All come from the book EXCEPT for Lanczos, which I took from Wikipedia (and adapted). Warning: you are getting a glimpse into how my solution works (yes, its designed for simplicity, not for efficiency).
class Filter {
public:
Filter(float rad, string& nm) : radius(rad), name(nm) {};
string name;
float radius; // should be an over statement (so you get some zeros)
virtual float eval(float) = 0;
};
class BoxFilter : public Filter {
public:
BoxFilter() : Filter(1,string("Box")) {};
virtual float eval(float t) {
return ( (t>=-.5) && (t<.5) ) ? ((float)1) : ((float)0);
};
};
class TentFilter : public Filter {
public:
TentFilter() : Filter(1,string("Tent")) {};
virtual float eval(float t) {
float x = abs(t);
return ( x>1 ) ? 0.0f : (1.0f - x);
};
};
// from p90 of Shirley
static float cubed(float x) { return x*x*x; }
static float squared(float x) { return x*x; }
class BSplineFilter : public Filter {
public:
BSplineFilter() : Filter(2,string("CubicBSpline")) { };
virtual float eval(float x) {
float a = abs(x);
float m = 1.0f-a;
if (a<=1) return (-3.0f * m*m*m + 3.0f*m*m + 3*m + 1) / 6.0f;
if (a<2) return cubed(2.0f - a) / 6.0f;
return 0;
};
};
// p91 of Shirley
class CatRomFilter : public Filter {
public:
CatRomFilter() : Filter(2,string("Catmull-Rom")) { };
virtual float eval(float x) {
float a = abs(x);
float m = 1.0f-a;
if (a<=1) return (-3.0f * m*m*m + 4.0f*m*m + m) / 2.0f;
if (a<2) return (cubed(2.0f - a) - squared(2.0f-a)) /2;;
return 0;
};
};
class MitchellNetravali : public Filter {
public:
MitchellNetravali() : Filter(2,string("Mitchell-Netravali")) {};
virtual float eval(float x) {
float a = abs(x);
float m = 1.0f-a;
if (a<=1) return (-21.0f * m*m*m + 27.0f*m*m + 9*m + 1) / 18.0f;
if (a<2) return (7.0f*cubed(2.0f - a) - 6.0f*squared(2.0f-a)) / 18.0f;
return 0;
};
};
// taken from the WikiPedia page
class Lanczos : public Filter
{
public:
Lanczos(float radius) : Filter(radius,string("Lanczos")+stringify(radius)) {};
float eval(float x) {
if (x == 0.0) return 1.0;
if (x <= -radius || x >= radius) return 0.0;
float pi_x = x * fpi;
return radius * sin(pi_x) * sin(pi_x / radius) / (pi_x * pi_x);
}
};
|