C# 为什么我的c代码这么慢

C# 为什么我的c代码这么慢,c#,performance,C#,Performance,Tihs是一个实现自适应直方图均衡化算法的代码,由c#main表单中的按钮调用,图像大小约为1024*768。问题是这个代码太慢了,我不知道应该在哪里修改以提高性能…请给我一些建议…谢谢 private void AHE_BMP_advanced(Int32 halfblocksize) { //adaptive histogram equalization Size imgsz = sourceBMP.Size; //compute total number of pi

Tihs是一个实现自适应直方图均衡化算法的代码,由c#main表单中的按钮调用,图像大小约为1024*768。问题是这个代码太慢了,我不知道应该在哪里修改以提高性能…请给我一些建议…谢谢

private void AHE_BMP_advanced(Int32 halfblocksize)
{
    //adaptive histogram equalization
    Size imgsz = sourceBMP.Size;
    //compute total number of pixels
    double totalNum = imgsz.Height * imgsz.Width;
    //temp image for storation
    Bitmap tempImg = new Bitmap(imgsz.Width, imgsz.Height);
    //region statistics
    double[,] prob = new double[256, 3];
    Int32[,] mapping = new Int32[256, 3];
    double[] probSum = new double[3];

    for (int i = 0; i < imgsz.Height; i++)
    {
        for (int j = 0; j < imgsz.Width; j++)
        {
            //this.textBox2.Text = "i=" + i.ToString() + "j=" + j.ToString();

            for (int u = 0; u < 256; u++) {
                for (int v = 0; v < 3; v++) {
                    prob[u, v] = 0;
                    mapping[u, v] = 0;
                }
            }

            //produce ahe for this pixel:
            for (int u = i - halfblocksize; u <= i + halfblocksize; u++)
            {
                for (int v = j - halfblocksize; v <= j + halfblocksize; v++)
                {
                    //uv->hi,wi;
                    int hi, wi;
                    hi = u;
                    wi = v;
                    //mirror:
                    if (hi < 0) hi = -hi;
                    else if (hi >= imgsz.Height)
                        hi = 2 * (imgsz.Height - 1) - hi;
                    if (wi < 0) wi = -wi;
                    else if (wi >= imgsz.Width)
                        wi = 2 * (imgsz.Width - 1) - wi;
                    //get hist

                    prob[sBmpdata[wi,hi,0], 0] += 1;
                    prob[sBmpdata[wi,hi,1], 1] += 1;
                    prob[sBmpdata[wi,hi,2], 2] += 1;
                }
            }
            //get ahe value:
            //probSum init:
            probSum[0] = 0;
            probSum[1] = 0;
            probSum[2] = 0;

            for (int k = 0; k < 256; k++)
            {                        
                this.textBox2.Text += "prob[" + k.ToString()+ ",0]=" +
                    prob[k,0].ToString()+"\r\n";

                prob[k, 0] /= totalNum;
                prob[k, 1] /= totalNum;
                prob[k, 2] /= totalNum;
                //Sum
                probSum[0] += prob[k, 0];
                probSum[1] += prob[k, 1];
                probSum[2] += prob[k, 2];
                if(i==40&&j==40)
                //mapping(INT32)
                mapping[k, 0] = Convert.ToInt32(255.0 * probSum[0]);
                mapping[k, 1] = Convert.ToInt32(255.0 * probSum[1]);
                mapping[k, 2] = Convert.ToInt32(255.0 * probSum[2]);
            }

            tempImg.SetPixel(j, i,
                Color.FromArgb(mapping[sBmpdata[j,i,0], 0],
                mapping[sBmpdata[j,i,1], 1], mapping[sBmpdata[j,i,2], 2]));
        }
    }

    this.pictureBox1.Image = tempImg;

}
private void AHE\u BMP\u高级(Int32半块大小)
{
//自适应直方图均衡化
Size imgsz=sourceBMP.Size;
//计算像素总数
double totalNum=imgsz.高度*imgsz.宽度;
//用于存储的温度图像
位图tempImg=新位图(imgsz.Width,imgsz.Height);
//区域统计
double[,]prob=新的double[256,3];
Int32[,]映射=新的Int32[256,3];
double[]probSum=新的double[3];
对于(int i=0;i=imgsz.宽度)
wi=2*(imgsz.宽度-1)-wi;
//了解历史
prob[sBmpdata[wi,hi,0],0]+=1;
prob[sBmpdata[wi,hi,1],1]+=1;
prob[sBmpdata[wi,hi,2],2]+=1;
}
}
//获取ahe值:
//probSum init:
probSum[0]=0;
probSum[1]=0;
probSum[2]=0;
对于(int k=0;k<256;k++)
{                        
this.textBox2.Text+=“prob[”+k.ToString()+”,0]=”+
prob[k,0].ToString()+“\r\n”;
prob[k,0]/=totalNum;
prob[k,1]/=totalNum;
prob[k,2]/=totalNum;
//总数
probSum[0]+=prob[k,0];
probSum[1]+=prob[k,1];
probSum[2]+=prob[k,2];
如果(i==40&&j==40)
//映射(INT32)
映射[k,0]=Convert.ToInt32(255.0*probSum[0]);
映射[k,1]=Convert.ToInt32(255.0*probSum[1]);
映射[k,2]=Convert.ToInt32(255.0*probSum[2]);
}
温度设定像素(j,i,
Color.FromArgb(映射[sBmpdata[j,i,0],0],
映射[sBmpdata[j,i,1],映射[sBmpdata[j,i,2],2]);
}
}
this.pictureBox1.Image=tempImg;
}
SetPixel
SetPixel
速度非常慢。查看如何使用
锁位
。他有很好的榜样

循环内的字符串串联 循环中的这条线效率也很低,因为它为每个像素创建256个字符串,所以分配了2.01亿个字符串,这一定很昂贵

for (int k = 0; k < 256; k++)
    this.textBox2.Text += "prob[" + k.ToString()+ ",0]=" + prob[k,0].ToString()+"\r\n";
for(int k=0;k<256;k++)
this.textBox2.Text++=“prob[”+k.ToString()+”,0]=“+prob[k,0].ToString()+”\r\n”;
如果是调试,请将其取出,2.01亿行调试文本对您没有用处。如果您需要它,最好将其写入文件,否则将需要许多GB的ram来存储最终字符串。

SetPixel
SetPixel
速度非常慢。查看如何使用
锁位
。他有很好的榜样

循环内的字符串串联 循环中的这条线效率也很低,因为它为每个像素创建256个字符串,所以分配了2.01亿个字符串,这一定很昂贵

for (int k = 0; k < 256; k++)
    this.textBox2.Text += "prob[" + k.ToString()+ ",0]=" + prob[k,0].ToString()+"\r\n";
for(int k=0;k<256;k++)
this.textBox2.Text++=“prob[”+k.ToString()+”,0]=“+prob[k,0].ToString()+”\r\n”;

如果是调试,请将其取出,2.01亿行调试文本对您没有用处。如果您需要,最好写入文件,否则需要很多GB的ram来存储最终字符串。

使用SetPixel实际上是处理图像数据的一种相当低效的方法。如果您想扫描整个图像,我建议您直接使用类来处理图像数据

//创建一个新位图。
位图bmp=新位图(“c:\\fakePhoto.jpg”);
//锁定位图的位。
矩形rect=新矩形(0,0,bmp.Width,bmp.Height);
System.Drawing.Imaging.BitmapData bmpData=
bmp.LockBits(rect,System.Drawing.Imaging.ImageLockMode.ReadWrite,
像素格式);
//获取第一行的地址。
IntPtr ptr=bmpData.Scan0;
//声明一个数组以保存位图的字节。
int bytes=Math.Abs(bmpData.Stride)*bmp.Height;
字节[]rgbValues=新字节[字节];
//将RGB值复制到数组中。
System.Runtime.InteropServices.Marshal.Copy(ptr,rgbvalue,0,字节);
//将每三个值设置为255。24bpp位图将显示为红色。
对于(int counter=2;counter
使用SetPixel实际上是处理图像数据的一种相当低效的方法。如果您想扫描整个图像,我建议您直接使用类来处理图像数据

//创建一个新位图。
位图bmp=新位图(“c:\\fakePhoto.jpg”);
//锁定位图的位。
矩形rect=新矩形(0,0,bmp.Width,bmp.Height);
System.Drawing.Imaging.BitmapData bmpData=
bmp.LockBits(rect,System.Drawing.Imaging.ImageLockMode.ReadWrite,
像素格式);
//获取第一行的地址。
IntPtr ptr=bmpData.Scan0;
//声明一个数组以保存位图的字节。
int bytes=Math.Abs(b
    private void AHE_BMP_advanced(Int32 halfblocksize)
    {
        this.pictureBox1.Image = GetAHE_BMP_advanced(halfblocksize, sourceBMP.Size, sBmpdata);
    }
    private static Bitmap GetAHE_BMP_advanced(int halfblocksize, Size sourceBmpSize, int[,,] sourceBmpData)
    {
        const int m = 256;
        const int n = 3;
        //adaptive histogram equalization
        Size imgsz = sourceBmpSize;
        //compute total number of pixels
        double totalNum = imgsz.Height * imgsz.Width;

        var colors = new Color[sourceBmpSize.Width, sourceBmpSize.Height];
        for (int i = 0; i < imgsz.Height; i++)
        {
            for (int j = 0; j < imgsz.Width; j++)
            {
                double[,] prob = new double[m, n];
                int[,] mapping = new int[m, n];

                //produce ahe for this pixel:
                for (int u = i - halfblocksize; u <= i + halfblocksize; u++)
                {
                    for (int v = j - halfblocksize; v <= j + halfblocksize; v++)
                    {
                        int hi = u;
                        int wi = v;
                        //mirror:
                        if (hi < 0) hi = -hi;
                        else if (hi >= imgsz.Height)
                            hi = 2 * (imgsz.Height - 1) - hi;
                        if (wi < 0) wi = -wi;
                        else if (wi >= imgsz.Width)
                            wi = 2 * (imgsz.Width - 1) - wi;
                        //get hist

                        prob[sourceBmpData[wi, hi, 0], 0] += 1;
                        prob[sourceBmpData[wi, hi, 1], 1] += 1;
                        prob[sourceBmpData[wi, hi, 2], 2] += 1;
                    }
                }

                double[] probSum = new double[n];

                for (int k = 0; k < m; k++)
                {

                    prob[k, 0] /= totalNum;
                    prob[k, 1] /= totalNum;
                    prob[k, 2] /= totalNum;
                    //Sum
                    probSum[0] += prob[k, 0];
                    probSum[1] += prob[k, 1];
                    probSum[2] += prob[k, 2];
                    if (i == 40 && j == 40) //mapping(INT32)
                    {
                        mapping[k, 0] = Convert.ToInt32(255.0 * probSum[0]);
                        mapping[k, 1] = Convert.ToInt32(255.0 * probSum[1]);
                        mapping[k, 2] = Convert.ToInt32(255.0 * probSum[2]);
                    }
                }

                colors[i, j] = Color.FromArgb(mapping[sourceBmpData[j, i, 0], 0],
                                              mapping[sourceBmpData[j, i, 1], 1],
                                              mapping[sourceBmpData[j, i, 2], 2]);
            }
        }

        return BitmapHelper.CreateBitmap(colors);
    }
        // ReSharper disable UnassignedField.Compiler
        public byte Blue;
        public byte Green;
        public byte Red;

        public bool Equals(Pixel other)
        {
            return Red == other.Red && Green == other.Green && Blue == other.Blue;
        }
    }

    public static Color[,] GetPixels(Bitmap two)
    {
        return ProcessBitmap(two, pixel => Color.FromArgb(pixel.Red, pixel.Green, pixel.Blue));
    }

    public static float[,] GetBrightness(Bitmap two)
    {
        return ProcessBitmap(two, pixel => Color.FromArgb(pixel.Red, pixel.Green, pixel.Blue).GetBrightness());
    }

    public static unsafe T[,] ProcessBitmap<T>(Bitmap bitmap, Func<Pixel, T> func)
    {
        var lockBits = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly,
                                   bitmap.PixelFormat);
        int padding = lockBits.Stride - (bitmap.Width * sizeof(Pixel));

        int width = bitmap.Width;
        int height = bitmap.Height;

        var result = new T[height, width];

        var ptr = (byte*)lockBits.Scan0;

        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                var pixel = (Pixel*)ptr;
                result[i, j] = func(*pixel);
                ptr += sizeof(Pixel);
            }
            ptr += padding;
        }

        bitmap.UnlockBits(lockBits);

        return result;
    }

    public static Bitmap CreateBitmap(Color[,] colors)
    {
        const int bytesPerPixel = 4, stride = 8;
        int width = colors.GetLength(0);
        int height = colors.GetLength(1);
        byte[] bytes = new byte[width*height*bytesPerPixel];


        int n = 0;
        for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < height; j++)
            {
                bytes[n++] = colors[i, j].R;
                bytes[n++] = colors[i, j].G;
                bytes[n++] = colors[i, j].B;
                bytes[n++] = colors[i, j].A;
            }
        }

        return CreateBitmap(bytes, width, height, stride, PixelFormat.Format32bppArgb);
    }

    public static Bitmap CreateBitmap(byte[] data, int width, int height, int stride, PixelFormat format)
    {
        var arrayHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
        var bmp = new Bitmap(width, height, stride, format, arrayHandle.AddrOfPinnedObject());
        arrayHandle.Free();
        return bmp;
    }
}