如何计算C#中多个位图图像的平均值 [英] How do I calculate average of multiple bitmap images in C#

查看:142
本文介绍了如何计算C#中多个位图图像的平均值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public 位图GetAveragedBitmap()
{

int numberOfImages = _imageCollection.Count;
位图bmpresult = null ;


if (numberOfImages > 1
{
秒表时钟= 秒表();
clock.Start();
BitmapData [] bmpData = new BitmapData [numberOfImages];
Bitmap [] bit = new 位图[numberOfImages];
int width = 0 ;
int height = 0 ;

for int index = 0 ; index < numberOfImages; index ++)
{
bmpData [index] = _imageCollection [index] .LockBits(< span class =code-keyword> new 矩形( 0 0 ,_ imageCollection [ index] .Width,_imageCollection [index] .Height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
if (index > 0
{
if (bmpData [index] .Width > width)
{
width = bmpData [index] .Width;
}
如果(bmpData [index] .Height > 身高)
{
height = bmpData [index] .Height;
}
}
else
{
width = bmpData [ 0 ]宽度。
height = bmpData [ 0 ]。高度;
}

_imageCollection [index] .UnlockBits(bmpData [index]);




} // end of for循环
for int index = 0 ; index < numberOfImages; index ++)
{
bit [index] = 位图(_imageCollection [index],width,height);

}

bmpresult = new 位图(宽度,高度);
BitmapData [] data = new BitmapData [numberOfImages];
for int index = 0 ; index < numberOfImages; index ++)
{
data [index] = bit [index] .LockBits( new 矩形( 0 0 ,位[index] .Width ,bit [index] .Height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
}
数据[ 1 ]。保留= 1 ;
BitmapData dataResult = bmpresult.LockBits( new 矩形( 0 0 ,bmpresult.Width,bmpresult.Height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);

不安全
{
int []仍然存在= new int [numberOfImages];
byte * [] ptr = new byte * [numberOfImages];
long totalIntensity = 0 ;

for int index = 0 ; index < numberOfImages; index ++)
{
ptr [index] =(byte *)data [index] .Scan0;
剩余[index] = data [index] .Stride - data [index] .Width * 3 ;
}
byte * ptrResult =(byte *)dataResult.Scan0;
// 生成的图片
int remainResult = dataResult.Stride - dataResult.Width * 3 ;


for int i = 0 ; i < height; i ++)
for int j = 0 ; j < width * 3 ; j ++)
{
for int index = 0 ; index < numberOfImages; index ++ )
{
totalIntensity + =( int )(ptr [index] [ 0 ]);
ptr [index] ++;
}
}

int average =( int )totalIntensity /(numberOfImages * height * width);
// 重置指针
for int index = 0 ; index < numberOfImages; index ++)
{
ptr [index] =(byte *)data [index] .Scan0;
}

for int i = 0 ; i < height; i ++)
{
for int j = 0 ; j < width * 3 ; j ++)
{

int result = 1 ;
for int k = 0 ; k < numberOfImages; k ++)
{

result =(ptr [k] [ 0 ] *结果);

}

// result = ptr [0] [ 0] +结果*(2 - 1);

ptrResult [ 0 ] =( byte )(结果/平均值);

for int index = 0 ; index < numberOfImages; index ++)
{
ptr [index] ++;
}
ptrResult ++;

}
for int index = 0 ; index < numberOfImages; index ++)
{
ptr [index] + = retain [指数];

}

ptrResult + = remainingResult;

}

// } // for循环结束

} // 不安全的结束

for int index = 0 ; index < numberOfImages; index ++)
{
bit [index] .UnlockBits(data [index]);
}
bmpresult.UnlockBits(dataResult);
clock.Stop();
Debug.WriteLine( 平均时间 + clock.ElapsedMilliseconds.ToString()) ;

}
return bmpresult;



}





我的尝试:



我已经尝试了上面的代码并得到了错误的结果(IncorrectOutput.jpg)。我正在附加图像集合。而且我附加了预期的图像(预期Output.jpg)。

图片链接

图像集合

解决方案

如果此代码符合您的要求(无论这是什么 - avarage 一个位图...,只需将输入参数更改为位图数组或列表,而不是在循环中完成所有操作5次 - 我无法想象你的问题是什么 - 你可以精心制作?除此之外,我建议将其拆分为:首先计算所需的最大图像,然后计算像素,...无论你在这里做什么......

=( byte < /()>(((ptr1 [ 0 ] + ptr2 [ 0 ] + ptr3 [ 0 ])+( 2 - 1 )* ptr4 [ 0 ] * ptr5 [ 0 ])/ average);



替换为

 ptrResult [ 0 ] =( byte )((ptr1 [ 0 ] + ptr2 [ 0 ] + ptr3 [ 0 ] + ptr4 [ 0 ] + ptr5 [ 0 ])/  5 ); 



应该更好。


public Bitmap GetAveragedBitmap()
    {

        int numberOfImages = _imageCollection.Count;
        Bitmap bmpresult = null;


        if (numberOfImages > 1)
        {
            Stopwatch clock = new Stopwatch();
            clock.Start();
            BitmapData[] bmpData = new BitmapData[numberOfImages];
            Bitmap[] bit = new Bitmap[numberOfImages];
            int width = 0;
            int height = 0;

            for (int index = 0; index < numberOfImages; index++)
            {
                bmpData[index] = _imageCollection[index].LockBits(new Rectangle(0, 0, _imageCollection[index].Width, _imageCollection[index].Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                if (index > 0)
                {
                    if (bmpData[index].Width > width)
                    {
                        width = bmpData[index].Width;
                    }
                    if (bmpData[index].Height > height)
                    {
                        height = bmpData[index].Height;
                    }
                }
                else
                {
                    width = bmpData[0].Width;
                    height = bmpData[0].Height;
                }

                _imageCollection[index].UnlockBits(bmpData[index]);




            }//end of for loop
            for (int index = 0; index < numberOfImages; index++)
            {
                bit[index] = new Bitmap(_imageCollection[index], width, height);

            }

            bmpresult = new Bitmap(width, height);
            BitmapData[] data = new BitmapData[numberOfImages];
            for (int index = 0; index < numberOfImages; index++)
            {
                data[index] = bit[index].LockBits(new Rectangle(0, 0, bit[index].Width, bit[index].Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            }
            data[1].Reserved = 1;
            BitmapData dataResult = bmpresult.LockBits(new Rectangle(0, 0, bmpresult.Width, bmpresult.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

            unsafe
            {
                int[] remain = new int[numberOfImages];
                byte*[] ptr = new byte*[numberOfImages];
                long totalIntensity = 0;

                for (int index = 0; index < numberOfImages; index++)
                {
                    ptr[index] = (byte*)data[index].Scan0;
                    remain[index] = data[index].Stride - data[index].Width * 3;
                }
                byte* ptrResult = (byte*)dataResult.Scan0;
                //for resultant image
                int remainResult = dataResult.Stride - dataResult.Width * 3;


                for (int i = 0; i < height; i++)
                    for (int j = 0; j < width * 3; j++)
                    {
                        for (int index = 0; index < numberOfImages; index++)
                        {
                            totalIntensity += (int)(ptr[index][0]);
                            ptr[index]++;
                        }
                    }

                int average = (int)totalIntensity / (numberOfImages * height * width);
                //reset the pointer
                for (int index = 0; index < numberOfImages; index++)
                {
                    ptr[index] = (byte*)data[index].Scan0;
                }

                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width * 3; j++)
                    {

                        int result = 1;
                        for (int k = 0; k < numberOfImages; k++)
                        {

                            result = (ptr[k][0] * result);

                        }

                       // result = ptr[0][0] + result * (2 - 1);

                        ptrResult[0] = (byte)(result / average);

                        for (int index = 0; index < numberOfImages; index++)
                        {
                            ptr[index]++;
                        }
                        ptrResult++;

                    }
                    for (int index = 0; index < numberOfImages; index++)
                    {
                        ptr[index] += remain[index];

                    }

                    ptrResult += remainResult;

                }

                //  }//end of for loop

            }//end of unsafe

            for (int index = 0; index < numberOfImages; index++)
            {
                bit[index].UnlockBits(data[index]);
            }
            bmpresult.UnlockBits(dataResult);
            clock.Stop();
            Debug.WriteLine("Time for average " + clock.ElapsedMilliseconds.ToString());

        }
        return bmpresult;



    }



What I have tried:

I have tried the above code and getting the wrong result(IncorrectOutput.jpg).I am attaching collection of images.And also I have attached expected image(Expected Output.jpg).
Link for the images
Collection Of Images

解决方案

if this Code does what you want (whatever this is - the "avarage" of a Bitmap...), just Change the Input Parameter to an Bitmap Array or list, and instead of doing everything 5 times do it in a Loop - I can't imagine what can be your problem with that - can you eleborate? Other from that I would recomend to split this up a Llttle: First calculate "biggest" image needed, then calculate Pixels, ... whatever you do here...
[EDIT: and get rid of your Magic numbers... replace with meaningful constants)


The average of some values is sum of values divided by number of values.
At best this code is weird:

ptrResult[0] = (byte)(((ptr1[0] + ptr2[0] + ptr3[0]) + (2 - 1) * ptr4[0] * ptr5[0]) / average);


replacing with

ptrResult[0] = (byte)((ptr1[0] + ptr2[0] + ptr3[0] + ptr4[0] + ptr5[0]) / 5);


should be better.


这篇关于如何计算C#中多个位图图像的平均值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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