11module ImageProcessing.ImageProcessing
22
3+ open System
34open Brahma.FSharp
45open SixLabors.ImageSharp
56open SixLabors.ImageSharp .PixelFormats
67
8+ [<Struct>]
9+ type Image =
10+ val Data : array < byte >
11+ val Width : int
12+ val Height : int
13+ val Name : string
14+ new ( data , width , height , name ) =
15+ {
16+ Data= data
17+ Width = width
18+ Height = height
19+ Name = name
20+ }
21+
722let loadAs2DArray ( file : string ) =
823 let img = Image.Load< L8> file
924 let res = Array2D.zeroCreate img.Height img.Width
@@ -13,6 +28,12 @@ let loadAs2DArray (file:string) =
1328 printfn $" H=%A {img.Height} W=%A {img.Width}"
1429 res
1530
31+ let loadAsImage ( file : string ) =
32+ let img = Image.Load< L8> file
33+ let buf = Array.zeroCreate< byte> ( img.Width* img.Height)
34+ img.CopyPixelDataTo ( Span< byte> buf)
35+ Image( buf, img.Width, img.Height, System.IO.Path.GetFileName file)
36+
1637let save2DByteArrayAsImage ( imageData : byte [,]) file =
1738 let h = imageData.GetLength 0
1839 let w = imageData.GetLength 1
@@ -25,6 +46,10 @@ let save2DByteArrayAsImage (imageData: byte[,]) file =
2546 let img = Image.LoadPixelData< L8>( flat2Darray imageData, w, h)
2647 img.Save file
2748
49+ let saveImage ( image : Image ) file =
50+ let img = Image.LoadPixelData< L8>( image.Data, image.Width, image.Height)
51+ img.Save file
52+
2853let gaussianBlurKernel =
2954 [|
3055 [| 1 ; 4 ; 6 ; 4 ; 1 |]
@@ -103,32 +128,22 @@ let applyFilterGPUKernel (clContext: ClContext) localWorkSize =
103128let applyFiltersGPU ( clContext : ClContext ) localWorkSize =
104129 let kernel = applyFilterGPUKernel clContext localWorkSize
105130 let queue = clContext.QueueProvider.CreateQueue()
106- fun ( filters : list < float32 [][]>) ( img : byte [,]) ->
107- let imgH = img.GetLength 0
108- let imgW = img.GetLength 1
109- let img =
110- [| for x in 0 .. Array2D.length1 img - 1 do
111- yield ! [| for y in 0 .. Array2D.length2 img - 1 -> img.[ x, y] |]
112- |]
113- let clImage = clContext.CreateClArray<_> img
114-
115- //let mutable res = None
116- let mutable input = clImage// clContext.CreateClArray(img.Length, allocationMode = AllocationMode.Default)
117- let mutable output = clContext.CreateClArray( img.Length, allocationMode = AllocationMode.Default)
131+ fun ( filters : list < float32 [][]>) ( img : Image ) ->
132+
133+ let mutable input = clContext.CreateClArray<_> img.Data
134+ let mutable output = clContext.CreateClArray( img.Data.Length, allocationMode = AllocationMode.Default)
118135
119136 for filter in filters do
120137 let filter = Array.concat filter
121138 let filterD = ( Array.length filter) / 2
122- let clFilter = clContext.CreateClArray<_> filter
139+ let clFilter = clContext.CreateClArray<_>( filter, HostAccessMode.NotAccessible , DeviceAccessMode.ReadOnly )
123140 let oldInput = input
124- input <- kernel queue clFilter filterD input imgH imgW output
141+ input <- kernel queue clFilter filterD input img.Height img.Width output
125142 output <- oldInput
126143 queue.Post( Msg.CreateFreeMsg clFilter)
127144
128- let result ' = Array.zeroCreate ( imgH * imgW)
129- let result ' = queue.PostAndReply( fun ch -> Msg.CreateToHostMsg( input, result', ch))
130- let result = Array2D.zeroCreate imgH imgW
131- Array.Parallel.iteri ( fun x v -> result.[ x / imgW, x % imgW] <- v) result'
145+ let result = Array.zeroCreate ( img.Height * img.Width)
146+ let result = queue.PostAndReply( fun ch -> Msg.CreateToHostMsg( input, result, ch))
132147 queue.Post( Msg.CreateFreeMsg input)
133148 queue.Post( Msg.CreateFreeMsg output)
134- result
149+ Image ( result, img.Width , img.Height , img.Name )
0 commit comments