I tried to do my own implementation of ci::ip::resize, specialized for 2x downscaling. My code is pretty self-explanatory:
Array2D<float> downscale2x(Array2D<float> in) {
auto res = Array2D<float>(in.Size() / 2);
forxy(res) {
res(p) = .25f*(
in(p * 2)
+ in(p * 2 + ivec2(1, 0))
+ in(p * 2 + ivec2(0, 1))
+ in(p * 2 + ivec2(1, 1))
);
}
return res;
}
But this results in a strongly (visibly) aliased image.
OTOH, ci::ip::resize (with a default-constructed triangle filter) results in an image with no visible aliasing. How does it do that? I suspect it’s because the triangle filter has larger support than in my implementation.
And another question:
Does FilterBase’s filter support value mean half of the actual support? I’m asking because look:
class FilterTriangle : public FilterBase {
public:
FilterTriangle( float aSupport = 1.0f ) : FilterBase( aSupport ) {}
virtual float operator()( float x ) const {
if ( x < -1.0f ) return 0.0f;
else if ( x < 0.0f ) return 1.0f + x;
else if ( x < 1.0f ) return 1.0f - x;
return 0.0f;
}
};
Here, the default aSupport is 1.0f, yet the operator() implementation returns nonzeros for the (-1, 1) range, meaning that the support is actually 2.0f.
TIA