亮度差异.GetPixel(x,y).GetBrightness()与.LockBits方法 [英] Difference in Brightness .GetPixel(x,y).GetBrightness() vs. .LockBits Method
问题描述
处理我的项目,我遇到了一个新问题。我想加快我对位图亮度的整合。因此我得到了两种不同类型的计算算法。第一个是经典慢速算法,通过迭代像素并获得它们的颜色然后亮度:
private double GET_BRIGHTNESS_SLOW(Bitmap processedBitmap)
{
double 结果= 0 ;
double brg = 0 ;
for ( int x = 0 ; x < processedBitmap.Width; x ++)
{
for ( int y = 0 ; y < processedBitmap.Height; y ++)
{
brg = processedBitmap.GetPixel(x,y).GetBrightness();
if (brg > = BORDER)
结果+ = brg;
counter ++;
}
}
返回结果;
}
第二种算法使用LockBits方法和不安全代码:
private double GET_BRIGHTNESS(Bitmap processedBitmap)
{
double 结果= 0 ;
double brg = 0 ;
不安全
{
BitmapData bitmapData = processedBitmap.LockBits( new Rectangle( 0 , 0 ,processedBitmap.Width,processedBitmap.Height),ImageLockMode.ReadWrite,processedBitmap.PixelFormat );
int bytesPerPixel = System.Drawing.Bitmap.GetPixelFormatSize(processedBitmap.PixelFormat)/ 8 < /跨度>;
int heightInPixels = bitmapData.Height;
int widthInBytes = bitmapData.Width * bytesPerPixel;
byte * PtrFirstPixel =(byte *)bitmapData.Scan0;
for ( int y = 0 ; y < heightInPixels; y ++)
{
byte * currentLine = PtrFirstPixel +(y * bitmapData.Stride) ;
for ( int x = 0 ; x < widthInBytes; x = x + bytesPerPixel)
{
int Blue = currentLine [x];
int Green = currentLine [x + 1 ];
int 红色= currentLine [x + 2 ];
brg = Color.FromArgb(红色,绿色,蓝色).GetBrightness();
if (brg > = BORDER)
结果+ = brg;
counter ++;
}
}
processedBitmap.UnlockBits(bitmapData);
}
return 结果;
}
为了比较,我写了以下代码:
秒表sw = 新秒表();
sw.Start();
double result = GET_BRIGHTNESS(p_BMP);
sw.Stop();
MessageBox.Show( Counter: + counter.ToString()+ \\\\ nnTime: + sw.ElapsedMilliseconds + ms \\ nnValue: + Math.Round(结果, 2 )的ToString());
counter = 0 ;
sw.Reset();
sw.Start();
double result_sl = GET_BRIGHTNESS_SLOW(p_BMP);
sw.Stop();
MessageBox.Show( Counter: + counter.ToString()+ \\\\ nnTime: + sw.ElapsedMilliseconds + ms \\ nnValue: + Math.Round(result_sl, 2 ) .ToString());
结果是快速版:
< br />
计数器:325546< br />
时间:24毫秒< br />
价值:14437,37< br />
和慢速版:
< br />
计数器:325546< br />
时间:449毫秒< br />
价值:16367,6< br />
图片尺寸为659 x 494,因此325546像素,这两者都是正确的。以上结果适用于 BORDER = 0.25
。如果我设置 BORDER = 0
我得到:
快速版价值: 50220,87
和慢速版价值:50239,4
其中这种差异来自哪里?显然我想要纠正价值和快速代码...有没有人有想法?
你错过了alpha内容。int 蓝色= currentLine [x];
int Green = currentLine [x + 1 ];
int 红色= currentLine [x + 2 ];
int alpha = currentLine [x + 3 ]; // Alpha
可能正在制作最终输出的差异。
我自己找到了答案,但Abhinav带我走上了正确的道路...
for ( int x = 0 ; x < widthInBytes; x = x + bytesPerPixel)
{
int Blue = currentLine [x];
int Green = currentLine [x + 1 ];
int 红色= currentLine [x + 2 ];
是问题所在。由于我的图片是灰度,一个像素只有1个字节,所以通过将绿色设置为x + 1而红色设置为x + 2,我平均超过3个像素...
所以我直接更改为:
for ( int x = 0 ; x < widthInBytes; x = x + bytesPerPixel )
{
brg =(( double )currentLine [x] / 255。 00 跨度>);
现在一切都很好
Hallo together,
working on my project, I have an new problem. I want to speed up my integration of brightness of a bitmap. Therefor I got two different types of calculation algorithms. The first one is the "classical" slow algorithm by iterating through the pixels and get their color and then their brightness:
private double GET_BRIGHTNESS_SLOW(Bitmap processedBitmap)
{
double Result = 0;
double brg = 0;
for (int x = 0; x < processedBitmap.Width; x++)
{
for (int y = 0; y < processedBitmap.Height; y++)
{
brg = processedBitmap.GetPixel(x, y).GetBrightness();
if (brg >= BORDER)
Result += brg;
counter++;
}
}
return Result;
}
The second algorithm is using the LockBits method and unsafe code:
private double GET_BRIGHTNESS(Bitmap processedBitmap)
{
double Result = 0;
double brg = 0;
unsafe
{
BitmapData bitmapData = processedBitmap.LockBits(new Rectangle(0, 0, processedBitmap.Width, processedBitmap.Height), ImageLockMode.ReadWrite, processedBitmap.PixelFormat);
int bytesPerPixel = System.Drawing.Bitmap.GetPixelFormatSize(processedBitmap.PixelFormat) / 8;
int heightInPixels = bitmapData.Height;
int widthInBytes = bitmapData.Width * bytesPerPixel;
byte* PtrFirstPixel = (byte*)bitmapData.Scan0;
for (int y = 0; y < heightInPixels; y++)
{
byte* currentLine = PtrFirstPixel + (y * bitmapData.Stride);
for (int x = 0; x < widthInBytes; x = x + bytesPerPixel)
{
int Blue = currentLine[x];
int Green = currentLine[x + 1];
int Red = currentLine[x + 2];
brg= Color.FromArgb(Red, Green, Blue).GetBrightness();
if (brg >= BORDER)
Result += brg;
counter++;
}
}
processedBitmap.UnlockBits(bitmapData);
}
return Result;
}
For comparison I wrote the following Code:
Stopwatch sw = new Stopwatch();
sw.Start();
double result = GET_BRIGHTNESS(p_BMP);
sw.Stop();
MessageBox.Show("Counter: " + counter.ToString() + "\r\nTime: " + sw.ElapsedMilliseconds + " ms \r\nValue: " + Math.Round(result, 2).ToString());
counter = 0;
sw.Reset();
sw.Start();
double result_sl = GET_BRIGHTNESS_SLOW(p_BMP);
sw.Stop();
MessageBox.Show("Counter: "+counter.ToString()+"\r\nTime: " + sw.ElapsedMilliseconds + " ms \r\nValue: " + Math.Round(result_sl, 2).ToString());
The result is for the fast version:
<br /> Counter: 325546<br /> Time: 24 ms<br /> Value: 14437,37<br />
and for the slow version:
<br /> Counter: 325546<br /> Time: 449 ms<br /> Value: 16367,6<br />
The Pictures Size is 659 x 494, so 325546 px, thats correct for both. The results above are for BORDER = 0.25
. If i set BORDER = 0
I get:
for the fast version Value: 50220,87
and for the slow version Value: 50239,4
Where does this difference come from? Obviously I want to have to correct value and the fast code... Does anyone have an Idea?
You are missing the alpha content.int Blue = currentLine[x]; int Green = currentLine[x + 1]; int Red = currentLine[x + 2]; int alpha = currentLine[x + 3]; //Alpha
That could be making a difference in your final output.
I found the answer myself, but Abhinav brought me on the correct path...
for (int x = 0; x < widthInBytes; x = x + bytesPerPixel) { int Blue = currentLine[x]; int Green = currentLine[x + 1]; int Red = currentLine[x + 2];
is the problem. Because of my picture being grayscale, one pixel is only 1 Byte, so by setting green to x+1 and red to x+2 I made an average over 3 pixel...
So I changed that directly to:
for (int x = 0; x < widthInBytes; x = x + bytesPerPixel) { brg = ((double)currentLine[x]/255.00);
And now everything is perfectly fine
这篇关于亮度差异.GetPixel(x,y).GetBrightness()与.LockBits方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!