About Monkey 2 › Forums › Monkey 2 Code Library › Gaussian Blur Filter (port of public domain BlitzMax code by Queller)
Tagged: blur, convolution, convolve, filter, gauss, gaussian, kernel
This topic contains 0 replies, has 1 voice, and was last updated by DruggedBunny 5 months, 2 weeks ago.
-
AuthorPosts
-
September 6, 2018 at 3:25 am #15380
Quick port of BlitzMax Gaussian Blur Filter by Queller.
The demo will load an image specified by you, apply gaussian blur of level 10 (edit ,10 parameter for more/less blur) and save to desktop with randomised name of GaussFilter_Test_RndULong.png.
Only briefly tested, fixed error noted in archive.org thread! Note that it operates on, and returns, RGBA8 format images. Use Pixmap.Convert on the result if you need different output.
Monkey
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166#Import "<std>"Using std..' ID: 2364' Author: Queller' Date: 2008-11-26 17:10:55' Title: Gaussian Blur Filter' Description: A true Gaussian blur filter' http://www.blitzbasic.com/'======== Example ========Function Main ()Local filename:String = ""Assert (filename <> "", "Input path to an image on your computer!")Local pix:Pixmap = GaussianBlur (Pixmap.Load (filename), 10)pix.Save (DesktopDir () + "GaussFilter_Test_" + RndULong () + ".png")End'====== Example Ends ======Function GaussianBlur:Pixmap(tex:Pixmap, radius:Int)If radius <=0 Return texIf tex.Format <> PixelFormat.RGBA8 Then tex = tex.Convert (PixelFormat.RGBA8)Local texclone:Pixmap = tex.Copy() 'clone incoming textureLocal filter:GaussianFilter = New GaussianFilter 'instantiate a new gaussian filterfilter.radius = radius 'configure itReturn filter.apply(tex, texclone)End FunctionClass GaussianFilterField radius:DoubleField kernel:KernelMethod apply:Pixmap(src:Pixmap, dst:Pixmap)kernel = makekernel(radius)convolveAndTranspose(kernel, src, dst, src.Width, src.Height, True)convolveAndTranspose(kernel, dst, src, dst.Height, dst.Width, True)dst = NullGCCollect()Return srcEnd Method'Make a Gaussian blur kernel.Method makekernel:Kernel(radius:Double)Local r:Int = Int(Ceil(radius))Local rows:Int = r*2+1Local matrix:Double[] = New Double[rows]Local sigma:Double = radius/3.0Local sigma22:Double = 2*sigma*sigmaLocal sigmaPi2:Double = 2*Pi*sigmaLocal sqrtSigmaPi2:Double = Sqrt(sigmaPi2)Local radius2:Double = radius*radiusLocal total:Double = 0Local index:Int = 0For Local row:Int = -r To rLocal distance:Double = Double(row*row)If (distance > radius2)matrix[index] = 0Elsematrix[index] = Double(Exp(-(distance/sigma22)) / sqrtSigmaPi2)total = total + matrix[index]index = index + 1End IfNextFor Local i:Int = 0 Until rowsmatrix[i] = matrix[i]/total 'normalizes the gaussian kernelNextReturn mkernel(rows, 1, matrix)End MethodFunction mkernel:Kernel(w:Int, h:Int, d:Double[])Local k:Kernel = New Kernelk.width = wk.height = hk.data = dReturn kEnd FunctionMethod convolveAndTranspose(kernel:Kernel, in:Pixmap, out:Pixmap, width:Int, height:Int, alpha:Int)Local inba:UByte Ptr = in.DataLocal outba:UByte Ptr = out.DataLocal matrix:Double[] = kernel.getKernelData()Local cols:Int = kernel.getWidth()Local cols2:Int = cols/2For Local y:Int = 0 Until heightLocal index:Int = yLocal ioffset:Int = y*widthFor Local x:Int = 0 Until widthLocal r:Double = 0, g:Double = 0, b:Double = 0, a:Double = 0Local moffset:Int = cols2For Local col:Int = -cols2 To cols2Local f:Double = matrix[moffset+col]If (f <> 0)Local ix:Int = x+colIf ( ix < 0 )ix = 0Else If ( ix >= width)ix = width-1End IfLocal rgb:Int = Cast <Int Ptr> (inba)[ioffset+ix] ' Was Int Ptr inbaa = a + f *((rgb Shr 24) & $FF)b = b + f *((rgb Shr 16) & $FF)g = g + f *((rgb Shr 8) & $FF)r = r + f *(rgb & $FF)End IfNextLocal ia:IntIf alpha = True Then ia = clamp(Int(a+0.5)) Else ia = $FFLocal ir:Int =clamp( Int(r+0.5))Local ig:Int = clamp(Int(g+0.5))Local ib:Int = clamp(Int(b+0.5))Cast <Int Ptr> (outba)[index] =((ia Shl 24) | (ib Shl 16) | (ig Shl 8) | (ir Shl 0)) ' Was Int Ptr outbaindex = index + heightNextNextEnd MethodEndClass KernelField width:IntField height:IntField data:Double[]Method getKernelData:Double[]()Return dataEnd MethodMethod getWidth:Int()Return widthEnd MethodMethod getHeight:Int()Return heightEnd MethodEndFunction clamp:Int(val:Int)If val < 0Return 0ElseIf val > 255Return 255ElseReturn valEndIfEnd Function -
AuthorPosts
You must be logged in to reply to this topic.