| View previous topic :: View next topic |
| Author |
Message |
Moon2 Guest
|
Posted: Sat Nov 11, 2006 3:17 pm Post subject: TBitmap Speed issues again |
|
|
Hi there, i want to pass a 3x3 mask over an image, such as:
for(int r=1; r < Height-1;r++)
{
for(int c=1; c< Width-1;c++)
{
SumR=0;
SumG=0;
SumB=0;
for(int i=0; i <3;i++)//y pos in mask
{
for(int j=0; j<3;j++)//x pos in mask
{
ypos = r+(i-1);
xpos = c+(j-1);
color =
ColorToRGB(tBitmap->Canvas->Pixels[xpos][ypos]); //<================
SumR+=
GetRValue(color)*Sobel3_3x[i][j];
SumG+=
GetGValue(color)*Sobel3_3x[i][j];
SumB+=
GetBValue(color)*Sobel3_3x[i][j];
}
}
}//other stuff after this
So i look at a radius of 9 pixels going along a row. The thing is Pixels
method is just tooo slow here and using Scanline in this case would need it
to be called Height*Width*i times. Can anyone help or make a suggestion.
Much appreciated
Mike |
|
| Back to top |
|
 |
JD Guest
|
Posted: Sat Nov 11, 2006 5:46 pm Post subject: Re: TBitmap Speed issues again |
|
|
"Moon2" <sbi (AT) telkomsa (DOT) net> wrote:
It's all about optimization. For example:
for( int r=1; r < Height-1; r++ )
{
for( int c = 1; c< Width-1; c++ )
{
}
}
is best written (I prefer x and y because that's always how
the Width and Height are referenced):
int y,
XLimit = Bitmap->Width - 1,
YLimit = Bitmap->Height - 1;
for( int x = 1; x < XLimit; ++x )
{
for( y = 1; y < YLimit; ++y )
{
}
}
Notice that I declared y prior to the for loop. That's because
with each itteration of the x loop, y has to be created and
destroyed. Also notice that I used a pre-increment v/s a post
increment. Post increment causes a temporary to be created,
incremented and then assigned to the variable. Pre-incrementation
does not suffer from this overhead.
Then there's the loop limit variable. IIRC, unless you have
specific optimizations set, with every loop itteration, you're
code has to create a temporary, subtract one from it and then
compare it against the loop counter.
Then there's this:
SumR += GetRValue(color)*Sobel3_3x[i][j];
SumG += GetGValue(color)*Sobel3_3x[i][j];
SumB += GetBValue(color)*Sobel3_3x[i][j];
That's alot of overhead that doesn't have to be there. Prior
to entering the x loop, you could define a 3D array instead
with the R,G,B values already extracted.
| Quote: | [...] The thing is Pixels method is just tooo slow here and
using Scanline in this case would need it to be called
Height*Width*i times.
|
It's unclear to me what you're doing with:
ColorToRGB(tBitmap->Canvas->Pixels[xpos][ypos]);
but you can code it so that you only access the Bitmap's
ScanLine property Height times if you access them prior to
entering the x loop. For example:
BYTE R,G,B, **ScanLines = new *BYTE[ Bitmap->Height ];
for( int y = 0; y < Bitmap->Height; ++y )
{
ScanLines[y] = static_cast<BYTE*>( Bitmap->ScanLine[y] );
}
for( int x = 1; x < XLimit; ++x )
{
.....
R = ScanLines[ ypos ][ xpos * 3 + 0 ];
G = ScanLines[ ypos ][ xpos * 3 + 1 ];
B = ScanLines[ ypos ][ xpos * 3 + 2 ];
.....
}
delete [] ScanLines;
~ JD |
|
| Back to top |
|
 |
Michel Leunen Guest
|
Posted: Sat Nov 11, 2006 7:16 pm Post subject: Re: TBitmap Speed issues again |
|
|
Moon2 wrote:
| Quote: | The thing is Pixels
method is just tooo slow here and using Scanline in this case would need it
to be called Height*Width*i times.
|
Did you read Remy's answer to your other post on the same subject? He
already shows you how to avoid this.
Michel
--
----------------------------------------
Michel Leunen
mailto: see my homepage.
C++Builder, BCC5.5.1 Web site:
http://www.leunen.com/
---------------------------------------- |
|
| Back to top |
|
 |
Moon2 Guest
|
Posted: Sat Nov 11, 2006 9:21 pm Post subject: Re: TBitmap Speed issues again |
|
|
yes i did, and the thing is scanline is going to be to slow for this case.
| Quote: | Did you read Remy's answer to your other post on the same subject? He
already shows you how to avoid this. |
|
|
| Back to top |
|
 |
Moon2 Guest
|
Posted: Sat Nov 11, 2006 9:26 pm Post subject: Re: TBitmap Speed issues again |
|
|
Ok i think i might need to explain the problem a bit better. Scanline is
going to return me a row, at the height i specify. Example Scanline[2], this
will give me the entire row at y =2 in the bitmap. If u can picture placing
a mask of 9 pixels over the image. Such as:
[][][]****************** (*- the image data and []- the mask)
[][][]******************
[][][]******************
Now you see if i use a scanline propert im accessing only the 1 row where as
i need to access all 3 rows(what ever the filter size is, in this example
its 3.) Thats why i have the following
for(i=1; i<Height-1;i++)
{
for(j=1;j<Height-1;j++)
{
//Now here we have the center pixel of the mask so we want to look
at its neighbours
//since we have a 3x3 mask in this case we have the following
for(int r=0;r<3;r++)
{
for(int c=0;c<3;c++)
{
//use ColorToRGB cause i need the colour of that pixel of
the bitmap that is within the mask ie)
tBitmap->canvas->pixels[xpos][ypos]
//so I get it here
//once i get the color of that pixel i assign it to the
value that i have in my SobelArray
}
}
}
} |
|
| Back to top |
|
 |
Moon2 Guest
|
Posted: Sat Nov 11, 2006 9:28 pm Post subject: Re: TBitmap Speed issues again |
|
|
Thanks JD I will give it a try
| Quote: | ................
BYTE R,G,B, **ScanLines = new *BYTE[ Bitmap->Height ];
for( int y = 0; y < Bitmap->Height; ++y )
{
ScanLines[y] = static_cast<BYTE*>( Bitmap->ScanLine[y] );
}
for( int x = 1; x < XLimit; ++x )
{
.....
R = ScanLines[ ypos ][ xpos * 3 + 0 ];
G = ScanLines[ ypos ][ xpos * 3 + 1 ];
B = ScanLines[ ypos ][ xpos * 3 + 2 ];
.....
}
delete [] ScanLines;
~ JD
|
|
|
| Back to top |
|
 |
Moon2 Guest
|
Posted: Sat Nov 11, 2006 9:50 pm Post subject: Re: TBitmap Speed issues again |
|
|
Maybe this extra code might help explain. Im really sorry for taking up ur
guys time. I do really apprecate the help:
for(int y=1; y < Height-1;y++)//ignore first row, last row
{
for(int x=1; x< Width-1;x++)//ignore first column, last
column
{
SumR=0;
SumG=0;
SumB=0;
for(int i=0; i <3;i++)//y pos in mask
{
for(int j=0; j<3;j++)//x pos in mask
{
ypos = y+(i-1);
xpos = x+(j-1);
SumR+=
Pixel[xpos][ypos].red*Sobel3_3x[i][j];
SumG+=
Pixel[xpos][ypos].green*Sobel3_3x[i][j];
SumB+=
Pixel[ypos][xpos].blue*Sobel3_3x[i][j];
}
}
/*Check if sum is greater than the max grayscale*/
if(SumR > 255)
SumR = 255;
else if (SumR <0)
SumR = 0;
if(SumG > 255)
SumG = 255;
else if (SumG <0)
SumG = 0;
if(SumB > 255)
SumB = 255;
else if (SumB <0)
SumB = 0;
SobelTemp[y][x].rgbtRed = SumR;
SobelTemp[y][x].rgbtGreen = SumG;
SobelTemp[y][x].rgbtBlue = SumB;
}
} |
|
| Back to top |
|
 |
Jonathan Benedicto Guest
|
Posted: Sat Nov 11, 2006 10:20 pm Post subject: Re: TBitmap Speed issues again |
|
|
Moon2 wrote:
| Quote: | Maybe this extra code might help explain. Im really sorry for taking up ur
guys time. I do really apprecate the help:
|
Try this code instead:
// Untested
int i, j, x, y, w, h, Sobel3_3xValue;
RGBTRIPLE *Line;
std::vector<RGBTRIPLE*> Lines;
j = Height;
Lines.resize( j );
for( i = 0; i < j; ++i )
Lines[ i ] = ptBitmap->ScanLine[ i ];
w = Width - 1;
h = Height - 1;
for( y = 1; y < h; ++y )
{
for( x = 1; x < w; ++x )
{
SumR = 0;
SumG = 0;
SumB = 0;
for( i = 0; i < 3; ++i )
{
ypos = y + ( i - 1 );
Line = Lines[ ypos ];
for( j = 0; j < 3; ++j )
{
xpos = x + ( j - 1 );
Sobel3_3xValue = Sobel3_3x[i][j];
SumR += Line[xpos].rgbtRed * Sobel3_3xValue;
SumG += Line[xpos].rgbtGreen * Sobel3_3xValue;
SumB += Line[xpos].rgbtBlue * Sobel3_3xValue;
}
}
if( SumR > 255 )
SumR = 255;
else if( SumR < 0 )
SumR = 0;
if( SumG > 255 )
SumG = 255;
else if( SumG < 0 )
SumG = 0;
if( SumB > 255 )
SumB = 255;
else if( SumB < 0 )
SumB = 0;
SobelTemp[y][x].rgbtRed = SumR;
SobelTemp[y][x].rgbtGreen = SumG;
SobelTemp[y][x].rgbtBlue = SumB;
}
}
Jonathan |
|
| Back to top |
|
 |
Moon2 Guest
|
Posted: Sat Nov 11, 2006 10:29 pm Post subject: Re: TBitmap Speed issues again |
|
|
This is directed to Gambit, with this problem Im having now would i need to
use that getpixel and setpixel method. I posted in the other topic? It just
doesnt seem neccessary to scanline an image when all that is required at a
time is 9 pixels. The thing I could do at first is scanline the entire image
into a 2d array and then manipulate that, then write from the 2d array back
to the bitmap. I dunno???!!!? |
|
| Back to top |
|
 |
Moon2 Guest
|
Posted: Sat Nov 11, 2006 10:33 pm Post subject: Re: TBitmap Speed issues again |
|
|
THANKS A MIL JOHN!!!!!
"Jonathan Benedicto" <invalid (AT) nobody (DOT) com> wrote in message
news:4555f848 (AT) newsgroups (DOT) borland.com...
| Quote: | Moon2 wrote:
Maybe this extra code might help explain. Im really sorry for taking up
ur guys time. I do really apprecate the help:
Try this code instead:
// Untested
int i, j, x, y, w, h, Sobel3_3xValue;
RGBTRIPLE *Line;
std::vector<RGBTRIPLE*> Lines;
j = Height;
Lines.resize( j );
for( i = 0; i < j; ++i )
Lines[ i ] = ptBitmap->ScanLine[ i ];
w = Width - 1;
h = Height - 1;
for( y = 1; y < h; ++y )
{
for( x = 1; x < w; ++x )
{
SumR = 0;
SumG = 0;
SumB = 0;
for( i = 0; i < 3; ++i )
{
ypos = y + ( i - 1 );
Line = Lines[ ypos ];
for( j = 0; j < 3; ++j )
{
xpos = x + ( j - 1 );
Sobel3_3xValue = Sobel3_3x[i][j];
SumR += Line[xpos].rgbtRed * Sobel3_3xValue;
SumG += Line[xpos].rgbtGreen * Sobel3_3xValue;
SumB += Line[xpos].rgbtBlue * Sobel3_3xValue;
}
}
if( SumR > 255 )
SumR = 255;
else if( SumR < 0 )
SumR = 0;
if( SumG > 255 )
SumG = 255;
else if( SumG < 0 )
SumG = 0;
if( SumB > 255 )
SumB = 255;
else if( SumB < 0 )
SumB = 0;
SobelTemp[y][x].rgbtRed = SumR;
SobelTemp[y][x].rgbtGreen = SumG;
SobelTemp[y][x].rgbtBlue = SumB;
}
}
Jonathan
|
|
|
| Back to top |
|
 |
Moon2 Guest
|
Posted: Sat Nov 11, 2006 10:45 pm Post subject: Re: TBitmap Speed issues again |
|
|
| Sorry joh i dont think thats gonna work. But thanks for the reply |
|
| Back to top |
|
 |
Jonathan Benedicto Guest
|
Posted: Sat Nov 11, 2006 10:50 pm Post subject: Re: TBitmap Speed issues again |
|
|
Moon2 wrote:
| Quote: | Sorry joh i dont think thats gonna work. But thanks for the reply
|
What is/was wrong? Did it have compile errors?
Jonathan |
|
| Back to top |
|
 |
Moon2 Guest
|
Posted: Sat Nov 11, 2006 10:54 pm Post subject: Re: TBitmap Speed issues again |
|
|
how do i get lines to point at position xpos,ypos of the bitmap. Looks like
we pointing to an entire row. I could be wrong, NOTHING new to me
"Jonathan Benedicto" <invalid (AT) nobody (DOT) com> wrote in message
news:4555ff3f (AT) newsgroups (DOT) borland.com...
| Quote: | Moon2 wrote:
Sorry joh i dont think thats gonna work. But thanks for the reply
What is/was wrong? Did it have compile errors?
Jonathan
|
|
|
| Back to top |
|
 |
Moon2 Guest
|
Posted: Sat Nov 11, 2006 11:02 pm Post subject: Re: TBitmap Speed issues again |
|
|
No i was wrong, u need this
pixelVal = Lines[xpos];
SumR+= pixelVal[ypos].rgbtRed*Sobel3_3x[i][j]; |
|
| Back to top |
|
 |
Jonathan Benedicto Guest
|
Posted: Sat Nov 11, 2006 11:10 pm Post subject: Re: TBitmap Speed issues again |
|
|
Moon2 wrote:
| Quote: | pixelVal = Lines[xpos];
SumR+= pixelVal[ypos].rgbtRed*Sobel3_3x[i][j];
|
Wrong way round. Lines is the scanlines, from top to bottom:
pixelVal = Lines[ ypos ];
SumR+= pixelVal[ xpos ].rgbtRed*Sobel3_3x[i][j];
But I in that code I sent, I did have that.
Jonathan |
|
| Back to top |
|
 |
|