pradeepa
pradeepa

Reputation: 4164

Whats wrong in the following cpp Bucubic interpolation code for Image Resizing

I am trying to upsample an Image using Bicubic Interpoloation, I need the accurate values matching the cvResize() function of opencv, but the results of following code is not matching the results from cvResize(), can you take a look and help me to fix the bug.

Image *Image::resize_using_Bicubic(int w, int h) {
    float dx,dy;
    float x,y;
    float tx, ty;
    float i,j,m,n;

Image *result=new Image(w, h); tx = (float)this->m_width/(float)w; ty = (float)this->m_height/(float)h; for(i=0; i< w; i++) { for(j=0; j< h; j++) { x = i*tx; y = j*ty; dx = float(i-x)-(int)(i-x); dy = float(j-y)-(int)(j-y); float temp=0.0; for(m=-1;m<=2;m++) { for(n=-1;n<=2;n++) { int HIndex,WIndex; HIndex=(y+n); WIndex=(x+m); if (HIndex<0) { HIndex=0; } else if(HIndex>this->getHeight()) { HIndex=this->getHeight()-1; } if (WIndex<0) { WIndex=0; } else if(WIndex>this->getWidth()) { WIndex=this->getWidth()-1; } temp+=this->getPixel(HIndex,WIndex)*R(m-dx)*R(dy-n); } } result->setPixel(j, i, temp); } } return result;

}

Upvotes: 0

Views: 671

Answers (2)

Mark Ransom
Mark Ransom

Reputation: 308520

You haven't said how different the results are. If they're very close, say within 1 or 2 in each RGB channel, this could be explained simply by roundoff differences.

There is more than one algorithm for Bicubic interpolation. Don Mitchell and Arun Netravali did an analysis and came up with a single formula to describe a number of them: http://www.mentallandscape.com/Papers_siggraph88.pdf

Edit: One more thing, the individual filter coefficients should be summed up and used to divide the final value at the end, to normalize the values. And I'm not sure why you have m-dx for one and dy-n for the other, shouldn't they be the same sign?

r=R(m-dx)*R(dy-n);
r_sum+=r;
temp+=this->getPixel(HIndex,WIndex)*r;
. . .
result->setPixel(j, i, temp/r_sum);

Upvotes: 1

Paul R
Paul R

Reputation: 213130

Change:

            else if(HIndex>this->getHeight())

to:

            else if(HIndex >= this->getHeight())

and change:

            else if(WIndex>this->getWidth())

to:

            else if(WIndex >= this->getWidth())

EDIT

Also change:

    for(m=-1;m<=2;m++)
    {
        for(n=-1;n<=2;n++)

to:

    for(m = -1; m <= 1; m++)
    {
        for(n = -1; n <= 1; n++)

Upvotes: 0

Related Questions