基于.NET数字处理程序的框架设计

2008-02-22 09:38:25来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

接触数字图像处理最早是在高中,那时候PHOTOSHOP还是4.0,可能是因为先入为主的关系,到现在都没有学3DMAX之类的兴趣,2D到3D的飞跃估计是没我什么事了,舍不得那平方到立方的高薪....呵呵。
在上大学的时候,就和同学一起写过一些图像处理的程序,那个时候编程还很随意,考虑的只是如何实现,现在看来真正的技术是把握全局的能力,而不是灵光一现的神奇。前些日子接触了一些国外的图像处理程序,在这里算是作个总结,估计以后不会再针对性的研究图像处理方面的东西了。
以前的一个同学曾经跟我说过.net没有指针,现在很多培训课好像也是这么讲的,其实这是一个谬误。只是framework不推荐使用指针,尤其是在webservise,remoting等跨进程操作中,指针都是不安全的。但用过TC的各位都应该对指针的执行效率又深刻的印象,在批量运算大规模数据的需求下,指针是不二的选择。因而.net聪明的保留的保留了指针,并将其列入不安全方法集中。合理的使用指针将大幅度提高执行效率,我曾做过试验,对640*480的图像进行逐点运算,非指针运算要执行数分钟,而指针运算几乎是瞬间完成的。所以不要害怕使用指针。
其次就是数学,奉劝大家一定要弄明白了再写程序,数学课不是闹着玩的......想不明白就要躺在床上反复的想,我总觉得数学能预防老年痴呆。
言归正传,说说程序结构吧 :
Imaging项目(滤镜,纹理,图像模式)
Math项目(算法,边界,定制。及常用计算方法)
主程序项目
各举个例子来说明,我也来一回面向接口编程 ,

public interface IFilter
{
Bitmap Apply( Bitmap img );
}

举例来说明,我也来一回面向接口编程 ,各滤镜都要实现这个接口,接口定义还包括一个不生成实际图像,只生成二进制对象的借口定义,在这里暂不作考虑。以取反色滤镜为例
public Bitmap Apply( Bitmap srcImg )
{
// get source image size
int width = srcImg.Width;
int height = srcImg.Height;

PixelFormat fmt = ( srcImg.PixelFormat == PixelFormat.Format8bppIndexed ) ?
PixelFormat.Format8bppIndexed : PixelFormat.Format24bppRgb;

// lock source bitmap data
BitmapData srcData = srcImg.LockBits(
new Rectangle( 0, 0, width, height ),
ImageLockMode.ReadOnly, fmt );

// create new image
Bitmap dstImg = ( fmt == PixelFormat.Format8bppIndexed ) ?
AForge.Imaging.Image.CreateGrayscaleImage( width, height ) :
new Bitmap( width, height, fmt );

// lock destination bitmap data
BitmapData dstData = dstImg.LockBits(
new Rectangle( 0, 0, width, height ),
ImageLockMode.ReadWrite, fmt );

// copy image
Win32.memcpy( dstData.Scan0, srcData.Scan0, srcData.Stride * height );

// process the filter
ProcessFilter( dstData, fmt );

// unlock both images
dstImg.UnlockBits( dstData );
srcImg.UnlockBits( srcData );

return dstImg;
}


是该滤镜方法的入口,完成了处理前的准备工作,ProcessFilter同时调用每个滤镜类中共有的ProcessFilter方法,而这个ProcessFilter就是实现功能的关键所在了逐点运算或模版运算。
// Process the filter
private unsafe void ProcessFilter( BitmapData data, PixelFormat fmt )
{
int width = data.Width;
int height = data.Height;

int lineSize = width * ( ( fmt == PixelFormat.Format8bppIndexed ) ? 1 : 3 );
int offset = data.Stride - lineSize;

// do the job
byte * ptr = (byte *) data.Scan0.ToPointer( );

// invert
for ( int y = 0; y < height; y )
{
for ( int x = 0; x < lineSize; x , ptr )
{
// ivert each pixel
*ptr = (byte)( 255 - *ptr );
}
ptr = offset;
}
}

其中Format8bppIndexed是不必太关心的,个人认为设计初期可以不用考虑兼容它的问题。
下面来说说纹理,这个以前考虑得还不太多,但发现老外很喜欢玩这个,因为纹理在数学方面发挥的空间更大,我也不知道他们是怎么想出来的,凭空想可能还真是有难度,可能是他们谁在玩数学建模软件的时候发现这个玩法的,于是高数老师谁也不服谁,把算法玩的火火的。反正我觉得是这么回事。。。
public interface ITextureGenerator
{
/**//// <summary>
/// Generate texture
/// </summary>
float[,] Generate( int width, int height );

/**//// <summary>
/// Reset - regenerate internal random numbers
/// </summary>
void Reset( );
}
这是纹理生成器的实现接口,为了保证每次的纹理不同,还要更新随机数以作为计算参数
private Math.PerlinNoise noise = new Math.PerlinNoise( 1.0 / 32, 0.05, 0.5, 8 );
实现纹理细节还需要靠noise实现,因而需要实现许多种noise。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:ASP.NET底层架构探索之IE6的革新

下一篇:编程使用资源文件实现多语言页面(In Action)