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