您的位置:首页 > 编程语言 > C#

编写高效的C#图像处理程序

2011-07-24 02:06 357 查看
前些天阅读《各种图像处理类库的比较及选择(The Comparison of Image Processing Libraries)》,对后面的比较结果感觉怪异。对计算密集型运算,C#和C/C++的性能应该差别不大才是。为了探讨问题,做了以下实验。

本实验比较了五种方式进行图像灰度化计算:

(1)EmguCV实现,见 《各种图像处理类库的比较及选择(The Comparison of Image Processing Libraries)》 文中代码

(2)OpenCV/PInvoke实现,见 《各种图像处理类库的比较及选择(The Comparison of Image Processing Libraries)》 文中代码

(3)BitmapData实现,见 《各种图像处理类库的比较及选择(The Comparison of Image Processing Libraries)》 文中代码

(4)Array实现(ArgbImage8),核心代码如下:

(每一个)ImageChannel8 内含1个Byte数组Data。GrayscaleImage8 继承自 ImageChannel8 。 public class ArgbImage8 : ImageChannelSet8

{

public ImageChannel8 A { get { return this.Channels[0]; } }

public ImageChannel8 R { get { return this.Channels[0]; } }

public ImageChannel8 G { get { return this.Channels[0]; } }

public ImageChannel8 B { get { return this.Channels[0]; } }

public ArgbImage8(int width, int height)

: base(4, width, height)

{

}

public GrayscaleImage8 ToGrayscaleImage()

{

return ToGrayscaleImage(0.299, 0.587, 0.114);

}

public GrayscaleImage8 ToGrayscaleImage(double rCoeff, double gCoeff, double bCoeff)

{

GrayscaleImage8 img = new GrayscaleImage8(this.Width, this.Height);

Byte[] r = R.Data;

Byte[] g = G.Data;

Byte[] b = B.Data;

Byte[] dst = img.Data;

for (int i = 0; i < r.Length; i++)

{

dst = (Byte)(r * rCoeff + g * gCoeff + b * bCoeff);

}

return img;

}

//性能低下,先这样写了

public static ArgbImage8 CreateFromBitmap(Bitmap map)

{

if (map == null) throw new ArgumentNullException("map");

ArgbImage8 img = new ArgbImage8(map.Width, map.Height);

Byte[] a = img.A.Data;

Byte[] r = img.R.Data;

Byte[] g = img.G.Data;

Byte[] b = img.B.Data;

for (int row = 0; row < img.Height; row++)

{

for (int col = 0; col < img.Width; col++)

{

int index = row * img.Width + col;

Color c = map.GetPixel(col, row);

a[index] = c.A;

r[index] = c.R;

r[index] = c.R;

r[index] = c.R;

}

}

return img;

}

}

复制代码(5)C# 指针/unsafe 实现(ArgbImage32 ),核心代码如下: public class UnmanagedMemory<T> : IDisposable

where T : struct

{

public Int32 ByteCount { get; private set; }

public Int32 Length { get; private set; }

public IntPtr Start { get; private set; }

public Int32 SizeOfType { get; private set; }

public UnmanagedMemory(Int32 length)

{

Length = length;

SizeOfType = SizeOfT();

ByteCount = SizeOfType * length;

Start = Marshal.AllocHGlobal(ByteCount);

}

public void Dispose()

{

Dispose(true);

GC.SuppressFinalize(this);

}

protected virtual void Dispose(bool disposing)

{

if (false == disposed)

{

disposed = true;

Marshal.FreeHGlobal(Start);

}

}

private bool disposed;

~UnmanagedMemory()

{

Dispose(false);

}

private Int32 SizeOfT()

{

return Marshal.SizeOf(typeof(T));

}

}

public struct Argb32

{

public Byte Alpha;

public Byte Red;

public Byte Green;

public Byte Blue;

}

public class Argb32Image : UnmanagedMemory<Argb32>

{

private unsafe Argb32* m_pointer;

public unsafe Argb32* Pointer { get { return m_pointer; } }

public unsafe Argb32Image(int length)

: base(length)

{

m_pointer = (Argb32*)this.Start;

}

public unsafe Argb32 this[int index]

{

get { return *(m_pointer + index); }

set { *(m_pointer + index) = value; }

}

public Grayscale8Image ToGrayscaleImage()

{

return ToGrayscaleImage(0.299, 0.587, 0.114);

}

public unsafe Grayscale8Image ToGrayscaleImage(double rCoeff, double gCoeff, double bCoeff)

{

Grayscale8Image img = new Grayscale8Image(this.Length);

Argb32* p = Pointer;

Byte* to = img.Pointer;

Argb32* end = p + Length;

while (p != end)

{

*to = (Byte)(p->Red * rCoeff + p->Green * gCoeff + p->Blue * bCoeff);

p++;

to++;

}

return img;

}

public unsafe static Argb32Image CreateFromBitmap(Bitmap map)

{

if (map == null) throw new ArgumentNullException("map");

Argb32Image img = new Argb32Image(map.Width*map.Height);

Argb32* p = img.Pointer;

for (int row = 0; row < map.Height; row++)

{

for (int col = 0; col < map.Width; col++)

{

Color c = map.GetPixel(col, row);

p->Alpha = c.A;

p->Red = c.R;

p->Green = c.G;

p->Blue = c.B;

p++;

}

}

return img;

}

}

复制代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: