Main Page | Report this Page
 
   
Science Forum Index  »  Image Processing Forum  »  Borland C++ Bilinear Interpolation Implementation
Page 1 of 1    
Author Message
Mr B
Posted: Wed Nov 29, 2006 7:10 pm
Guest
Hi all,

I'm was wondering if anybody could help with my bilinear interpolation
problem? I've have origionally taken the code from this article
http://www.codeproject.com/cs/media/imageprocessing4.asp
and i'm trying to adapt it for directly accessing the bitmap pixel with
pointers. I am getting access violation errors when i try to run my
code, does anybody know what i'm doing wrong.

Thanks alot in advance

Graphics::TBitmap* C_DIProc::ImageScaleBLin(Graphics::TBitmap* bmpDest,
Graphics::TBitmap* bmpRef, int NewHeight, int NewWidth)
{
//adjust image for its new scale
bmpDest->Width = NewWidth;
bmpDest->Height = NewHeight;

int floor_x, floor_y, ceil_x, ceil_y;
double fraction_x, fraction_y, one_minus_x, one_minus_y;

double xFactor=(float)bmpRef->Width/(float)bmpDest->Width;
double yFactor=(float)bmpRef->Height/(float)bmpDest->Height;

RGBTRIPLE* ImagePixels;
RGBTRIPLE* RefPixels; // Origional image pixels which changes are
based on

//surrounding pixels
RGBTRIPLE* c1;
RGBTRIPLE* c2;
RGBTRIPLE* c3;
RGBTRIPLE* c4;

int b1, b2;

for (int yRef=0, yDest=0; yDest < bmpDest->Height; yDest++)
{
for (int xRef=0, xDest=0; xDest<bmpDest->Width; xDest++)
{
//find centre of point and get surrounding co-ordinates
floor_x = floor(xRef * xFactor);
floor_y = floor(yRef * yFactor);
ceil_x = floor_x + 1;
if (ceil_x >= bmpRef->Width) ceil_x = floor_x;
ceil_y = floor_y + 1;
if (ceil_y >= bmpRef->Height) ceil_y = floor_y;
fraction_x = xRef * xFactor - floor_x;
fraction_y = yRef * yFactor - floor_y;
one_minus_x = 1.0 - fraction_x;
one_minus_y = 1.0 - fraction_y;

//set c variables to point to surrounding boxes
c1 = (RGBTRIPLE*)bmpRef->ScanLine[floor_y];
c1 = c1 + floor_x;

c2 = (RGBTRIPLE*)bmpRef->ScanLine[floor_y];
c2 = c2 + ceil_x;

c3 = (RGBTRIPLE*)bmpRef->ScanLine[ceil_y];
c3 = c3 + floor_x;

c4 = (RGBTRIPLE*)bmpRef->ScanLine[ceil_y];
c4 = c4 + ceil_x;

b1 = (one_minus_x * c1->rgbtRed + fraction_x * c2->rgbtRed);
b2 = (one_minus_x * c3->rgbtRed + fraction_x * c4->rgbtRed);
ImagePixels->rgbtRed = (one_minus_y * double(b1) + fraction_y *
(double)(b2));

b1 = (one_minus_x * c1->rgbtGreen + fraction_x * c2->rgbtGreen);
b2 = (one_minus_x * c3->rgbtGreen + fraction_x * c4->rgbtGreen);
ImagePixels->rgbtGreen = (one_minus_y * double(b1) + fraction_y *
(double)(b2));

b1 = (one_minus_x * c1->rgbtBlue + fraction_x * c2->rgbtBlue);
b2 = (one_minus_x * c3->rgbtBlue + fraction_x * c4->rgbtBlue);
ImagePixels->rgbtBlue = (one_minus_y * double(b1) + fraction_y *
(double)(b2));

ImagePixels++;
}
}
}
Lord Crc
Posted: Wed Nov 29, 2006 8:09 pm
Guest
On 29 Nov 2006 15:10:45 -0800, "Mr B" <mrb_16@hotmail.com> wrote:

Quote:
//adjust image for its new scale
bmpDest->Width = NewWidth;
bmpDest->Height = NewHeight;

I assume you've ensured that both source and dest are 24bpp (pf24Bit
in Delphi).

Quote:
RGBTRIPLE* ImagePixels;

As far as I can see, you don't assign ImagePixels... This would
certainly cause an AV.

Quote:
for (int yRef=0, yDest=0; yDest < bmpDest->Height; yDest++)
{
ImagePixels = (RGBTRIPLE*)bmpDest->ScanLine[yRef];


think this should do...

Quote:
//set c variables to point to surrounding boxes
c1 = (RGBTRIPLE*)bmpRef->ScanLine[floor_y];
c1 = c1 + floor_x;

Just a performance note: ScanLine is not that fast, you should compute
all y related stuff before the x for loop, including the
floor_y/ceil_y scanline calls.

Quote:
b1 = (one_minus_x * c1->rgbtRed + fraction_x * c2->rgbtRed);

This can be computed more efficiently by using:
b1 = c1->rgbtRed + (c2->rgbtRed - c1->rgbtRed) * fraction_x;

(which is easier to read too imho)

Note: I don't code in C/C++ so my syntax may be off :)

- Asbjørn
aruzinsky
Posted: Wed Nov 29, 2006 10:49 pm
Guest
I have only done this sort of thing with Microsoft Visual C++. I suspect
that the Borland TBitmap object is similarly based on the Windows SDK, API
or whatever. In this case, the rows of the array are padded just enough so
that the number of bytes are an integer multiple of four and the padded
rows are contiguous in RAM. In a pointer implementation, you will have to
skip over this padding. Also, the byte ordering (in ascending RAM) of a
pixel is BGR, not RGB. I suggest that you bypass all the Borland crap and
define your own BGR class.
Mr B
Posted: Fri Dec 01, 2006 5:28 am
Guest
Thanks very much for the information and advice! It is now working, it
was simply forgetting to initialize the ImagePixels Pointer, I guess I
just panicked not really done any IP before.

Cheers
Dan
 
Page 1 of 1       All times are GMT - 5 Hours
The time now is Sat Oct 11, 2008 1:51 pm