亮度差异.GetPixel(x,y).GetBrightness()与.LockBits方法 [英] Difference in Brightness .GetPixel(x,y).GetBrightness() vs. .LockBits Method

查看:148
本文介绍了亮度差异.GetPixel(x,y).GetBrightness()与.LockBits方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一起工作,

处理我的项目,我遇到了一个新问题。我想加快我对位图亮度的整合。因此我得到了两种不同类型的计算算法。第一个是经典慢速算法,通过迭代像素并获得它们的颜色然后亮度:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆