使用FSharp 探索Dotnet图像处理功能1--反色变化_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 使用FSharp 探索Dotnet图像处理功能1--反色变化

使用FSharp 探索Dotnet图像处理功能1--反色变化

 2017/4/2 5:32:35  rigid  程序员俱乐部  我要评论(0)
  • 摘要:坚持写博客是最近的目标。加油。业余学习fsharp以来一直觉得这才是Dotnet开发,或者说所有开发者应该拥有的语言。配合VisualStudio的代码提示,即时执行窗口。开发程序有着极大的乐趣。最近想学习一些图像处理的相关知识。试着把Fsharp又捡了起来。边学边玩,希望两个方面都有所进益。图像的处理首先要解决显示的问题。在FSI中内嵌了Winform的消息处理,可以很方便的几句话画出一个带PictureBox的窗体。在FSI中由于可以保持对窗体和控件的控制权,当更新算法后
  • 标签:功能 使用 net 变化 ARP 图像处理

坚持写博客是最近的目标。加油。

业余学习fsharp以来一直觉得这才是Dotnet开发,或者说所有开发者应该拥有的语言。配合Visual Studio的代码提示,即时执行窗口。开发程序有着极大的乐趣。

最近想学习一些图像处理的相关知识。试着把Fsharp又捡了起来。边学边玩,希望两个方面都有所进益。

图像的处理首先要解决显示的问题。在FSI中内嵌了Winform的消息处理,可以很方便的几句话画出一个带PictureBox的窗体。在FSI中由于可以保持对窗体和控件的控制权,当更新算法后,我们可以很快的看到结果。拥有即时反馈的编程工具真是开发人员的幸运。

open System.Windows.Forms

let form = new Form()
let image = new PictureBox(Dock = DockStyle.Fill)
form.Controls.Add(image)
image.SizeMode <- PictureBoxSizeMode.StretchImage
form.Show()

显示窗体的代码如上所示,非常的简单。当然此时什么都没有。下面来加载一张图片

open System.Drawing

let image_path = __SOURCE_DIRECTORY__ +  @"\Chrysanthemum.jpg"
let bitmap = new Bitmap(image_path)

image.Image <- bitmap 

好了最基本的框架完成了。此时我们仍可以通过bitmap,image等变量控制窗口的显示。

最后是反色程序,首先我们取出所有像素点

let Pixels =seq {for h in 0..bitmap.Height-1 do
                    for w in 0..bitmap.Width-1 do
                         yield bitmap.GetPixel(w, h)}

进行反色操作

Pixels |> Seq.iteri(fun i c -> 
                        bitmap.SetPixel(i%bitmap.Width,
                                        i/bitmap.Width, 
                                        Color.FromArgb((255 - (int c.R)), (255 - (int c.G)), (255 - (int c.B)))))
//win10 seem to need to update manually
image.Invalidate()

很简单吧。就是速度哦有些慢。主要是SetPixel和GetPixel操作拖累了速度。

使用BitmapData可以大大加快速度。使用#time 操作打开操作时间显示看看快了多少

let imagerect = new Rectangle(0,0,bitmap.Width, bitmap.Height)
let bitmapdata = bitmap.LockBits(imagerect, ImageLockMode.ReadWrite, bitmap.PixelFormat)
let buffer:byte[] = Array.zeroCreate (bitmap.Width * bitmap.Height * Bitmap.GetPixelFormatSize(bitmap.PixelFormat)/8)
Marshal.Copy(bitmapdata.Scan0, buffer, 0,  buffer.Length)
let newbuff = buffer |> Seq.map(fun x -> 255uy - x) |> Array.ofSeq
Marshal.Copy(newbuff, 0, bitmapdata.Scan0, buffer.Length)
bitmap.UnlockBits(bitmapdata)

image.Invalidate()
Real: 00:00:01.227,CPU: 00:00:01.218,GC gen0: 0, gen1: 0, gen2: 0

Real: 00:00:00.050,CPU: 00:00:00.046,GC gen0: 0, gen1: 0, gen2: 0

下次再找个知识点,不过似乎要先补补微积分和线代了。

 

发表评论
用户名: 匿名