Coding Bilinear Interpolation (original) (raw)
Pages: 1 2
Source code in action
Below is some code which simply rotates an image a certain number of radians. Bilinear interpolation is used in order to produce a quality final result. OpenMP is used so that high performance can be achieved on multi-core systems even though this code was made more for demonstration purposes than performance purposes.
unsigned int getR(unsigned int in) { return ((in & 0x00ff0000) >> 16); } unsigned int getG(unsigned int in) { return ((in & 0x0000ff00) >> 8); } unsigned int getB(unsigned int in) { return ((in & 0x000000ff)); } void CImageProcessor::Rotate(Bitmap * pBitmap, double angle) { int width = pBitmap->GetWidth(); int height = pBitmap->GetHeight(); double cX = (double)width/2.0f; double cY = (double)height/2.0f; BitmapData bitmapData; pBitmap->LockBits(&Rect(0,0,pBitmap->GetWidth(), pBitmap->GetHeight()), ImageLockModeWrite, PixelFormat32bppARGB, &bitmapData); unsigned int pRawBitmapOrig = (unsigned int)bitmapData.Scan0; unsigned int pBitmapCopy = new unsigned int[bitmapData.Strideheight/4]; memcpy(pBitmapCopy, pRawBitmapOrig, (bitmapData.Strideheight/4) * sizeof(unsigned int)); int nPixels = heightbitmapData.Stride/4; #pragma omp parallel for for (int i=0; i < height; i++) { double relY = cY-i; for (int j=0; j < width; j++) { double relX = j-cX; double xPrime = relXcos(angle) + relYsin(angle); double yPrime = -1 * relXsin(angle) + relYcos(angle); xPrime += cX; yPrime += cY; int q12x = (int)floor(xPrime); int q12y = (int)floor(yPrime); q12x = max(0, q12x); q12y = max(0, q12y); q12x = min(width-1, q12x); q12y = min(height-1, q12y); int q22x = (int)ceil(xPrime); int q22y = q12y; q22x = min(width-1, q22x); q22x = max(0, q22x); int q11x = q12x; int q11y = (int)ceil(yPrime); q11y = min(height-1, q11y); q11y = max(0, q11y); int q21x = q22x; int q21y = q11y; unsigned int q11 = pBitmapCopy[q11ybitmapData.Stride/4 + q11x]; unsigned int q12 = pBitmapCopy[q12ybitmapData.Stride/4 + q12x]; unsigned int q21 = pBitmapCopy[q21ybitmapData.Stride/4 + q21x]; unsigned int q22 = pBitmapCopy[q22ybitmapData.Stride/4 + q22x]; unsigned int q11r = getR(q11); unsigned int q11g = getG(q11); unsigned int q11b = getB(q11); unsigned int q12r = getR(q12); unsigned int q12g = getG(q12); unsigned int q12b = getB(q12); unsigned int q21r = getR(q21); unsigned int q21g = getG(q21); unsigned int q21b = getB(q21); unsigned int q22r = getR(q22); unsigned int q22g = getG(q22); unsigned int q22b = getB(q22); double factor1; double factor2;
if ( q21x == q11x ) {
factor1 = 1; factor2 = 0;
}
else
{
factor1 = (((double)q21x - (double)xPrime)/((double)q21x - (double)q11x));
factor2 = (((double)xPrime - (double)q11x)/((double)q21x - (double)q11x));
}
double R1r = factor1 * (double)q11r + factor2*(double)q21r;
double R1g = factor1 * (double)q11g + factor2*(double)q21g;
double R1b = factor1 * (double)q11b + factor2*(double)q21b;
double R2r = factor1 * (double)q12r + factor2*(double)q22r;
double R2g = factor1 * (double)q12g + factor2*(double)q22g;
double R2b = factor1 * (double)q12b + factor2*(double)q22b;
double factor3;
double factor4;
if (q12y == q11y) {
factor3 = 1;
factor4 = 0;
}
else
{
factor3 = ((double) q12y - yPrime)/((double)q12y - (double)q11y);
factor4 = (yPrime - (double)q11y)/((double)q12y - (double)q11y);
} unsigned int finalR = (unsigned int)((factor3 * R1r) + (factor4*R2r));
unsigned int finalG = (unsigned int)((factor3 * R1g) + (factor4*R2g));
unsigned int finalB = (unsigned int)((factor3 * R1b) + (factor4*R2b)); finalR = min(255, finalR);
finalR = max(0, finalR);
finalG = min(255, finalG);
finalG = max(0, finalG);
finalB = min(255, finalB);
finalB = max(0, finalB);
unsigned int finalPixel = 0xff000000 | (finalR << 16) | (finalG << 8) | finalB;
pRawBitmapOrig[(height-i-1)*bitmapData.Stride/4 + j] = finalPixel; }
}
delete[] pBitmapCopy;
pBitmap->UnlockBits(&bitmapData);
}
Pages: 1 2
This entry was posted by admin on December 30, 2011 at 9:28 pm under C++, Graphics. Tagged Bilinear, Bilinear Interpolation, C++, Code, Example, Image, Image processing, Interpolation, Quality, Rotate, Source Code, Transform, Tutorial. Both comments and pings are currently closed.