BLUR FILTERHANPO
HANPOSBACE - Director of Visual & Interface DesignFreelancer - iOS UI/UX Designer ,iOS Developer ,Illustrator Portfoliohttp://hanpo.tw/ LinkedIntw.linkedin.com/in/hanpo/ Instagram http://instagram.com/ihanpo
Why?
i.Frame Exhibition
CamInstagram Path
Path
Cam
What?
How?
Image Data
Pixel
RGB 115,41,41 RGB 98,49,49 RGB 212,168,32
RGB 115,41,41 RGB 98,49,49 RGB 255,243,182
RGB 115,41,41 RGB 98,49,49 RGB 255,251,236
Image (2D array of pixels)
Naïve Box BlurBox blur - 3*3 Matrix of 1/9 * determinant matrix
11 1
11 1
11 1
Naïve Box Blur
RGB 115,41,41 RGB 98,49,49 RGB 212,168,32
RGB 115,41,41 RGB 98,49,49 RGB 255,243,182
RGB 115,41,41 RGB 98,49,49 RGB 255,251,236
RGB 151,104,80
Naïve Box BlurImage convolution - the convolution of a 2D image is O(m2*n2)
For it to be fast you must implement it as an accumulator, not a convolution loop.
for each row for each col set count to 0 for every neighboring pixel within the radius m in the x direction for every neighboring pixel within the radius m in the y direction add the color to the total count++ final_color = total/count setpixel(current x, current y, final_color)
Calculate all PixelsSample image 4 x 3 pixels, radius is 1
Box BlurR:0 R:1 R:3
R:6 R:10 R:20
Edge Handling
Better Box BlurFor it to be fast you must implement it as an accumulator, not a convolution loop.
Image convolution - the convolution of a 2D image is O(n^2 * 2m)
for each row for every neighboring pixel within the radius m in the x direction add the color to the total count++ final_color = total/count setpixel(current x, current y, final_color) !
repeat above for the columns
Calculate all PixelsSample image 6 x 6 pixels, radius is 2
in the x direction
in the y direction
if x <= r for var _i=i-x; _i<=i+r; _i++
if x > r && x < (w-r) for var _i=i-r; _i<=i+r; _i++
if x >= (w-r) for var _i=i-r; _i<=i+(w-x); _i++
if _y <= r for var _i=0; _i<=_y+r; _i++ let currentIndex = _i*w+_x
if r < _y && _y < (h-r) for var _i=_y-r; _i<=_y+r; _i++ let currentIndex = _i*w+_x
if _y >= (h-r) for var _i=_y-r; _i<=(h-1); _i++ let currentIndex = _i*w+_x
R:0 R:1 R:3
R:6 R:10 R:20
Better Box Blur
CompareBox Blur & Better Box Blur
Size: 512 x 512 Device: iPad mini 2
Box Blur Better Box Blur
Radius:1 112.4061s 7.1371s
Radius:2 300.8143s 7.1586s
Radius:3 586.2660s 7.2406s
Radius:6 1958.8380s 7.3746s
Radius:10 5017.5250s 7.6009s
Radius:20 8.1089s
Convolutionfor each image row in output image: for each pixel in image row: !
set accumulator to zero !
for each kernel row in kernel: for each element in kernel row: !
if element position corresponding* to pixel position then multiply element value corresponding* to pixel value add result to accumulator endif !
set output image pixel to accumulator
Accelerate FrameworkConsists of two frameworks: vImage and vecLib
Available in OS X v10.4 Use vector co-processor (CPU-based) Designed to run various mathematical operations with data Well optimized and uses SIMD
vImageAccelerate Framework
func vImageBoxConvolve_ARGB8888(_ src: UnsafePointer<vImage_Buffer>, _ dest: UnsafePointer<vImage_Buffer>, _ tempBuffer: UnsafeMutablePointer<Void>, _ srcOffsetToROI_X: vImagePixelCount, _ srcOffsetToROI_Y: vImagePixelCount, _ kernel_height: UInt32, _ kernel_width: UInt32, _ backgroundColor: UnsafeMutablePointer<UInt8>, _ flags: vImage_Flags) -> vImage_Error
vImage BlurR:0 R:1 R:3
R:6 R:10 R:20
Compare
Box Blur Better Box Blur vImage
Radius:1 112.4061s 7.1371s first: 0.0292s second: 0.0065s
Radius:2 300.8143s 7.1586s first:0.0260 second:0.0063
Radius:3 586.2660s 7.2406s first: 0.0410s second: 0.0066s
Radius:6 1958.8380s 7.3746s first: 0.0272s second: 0.0071s
Radius:10 5017.5250s 7.6009s first: 0.0294s second: 0.0063s
Radius:20 8.1089s first: 0.0281s second: 0.0073s
Box Blur & Better Box Blur & vImage Size: 512 x 512 Device: iPad mini 2
Gaussian Blur
0.00000067 0.00002292 0.00019117 0.00038771 0.00019117 0.00002292 0.00000067
0.00002292 0.00078633 0.00655965 0.01330373 0.00655965 0.00078633 0.00002292
0.00019117 0.00655965 0.05472157 0.11098164 0.05472157 0.00655965 0.00019117
0.00038771 0.01330373 0.11098164 0.22508352 0.11098164 0.01330373 0.00038771
0.00019117 0.00655965 0.05472157 0.11098164 0.05472157 0.00655965 0.00019117
0.00002292 0.00078633 0.00655965 0.01330373 0.00655965 0.00078633 0.00002292
0.00000067 0.00002292 0.00019117 0.00038771 0.00019117 0.00002292 0.00000067
r=3 ,σ = 0.84089642
Gaussian Distribution
in one dimension in two dimensions
Gaussian function
in one dimension
in two dimensions
Core Image - Gaussian Blurvar context: CIContext! let inputImage = CIImage(image: img) let gaussianBlurFilter = CIFilter(name:"CIGaussianBlur", withInputParameters: [kCIInputImageKey:inputImage,kCIInputRadiusKey:blurLevel]) let outputCIImage = gaussianBlurFilter.outputImage.imageByCroppingToRect(inputImage.extent()) context = CIContext(options:nil) let cgimg = context.createCGImage(outputCIImage, fromRect: outputCIImage.extent()) let outputImage = UIImage(CGImage: cgimg)
Gaussian Blur Speed
Level:1 0.1143s
Level:10 0.1192s
Level:100 0.1288s
Level:500 0.2334s
Level:680 0.1078s
Level:1000 0.1082s
Size: 512 x 512 Device: iPad mini 2Core Image - Gaussian Blur
Compare
Box Blur Gaussian Blur
Box Blur & Gaussian Blur
Compare
Box Blur Gaussian Blur
Box Blur & Gaussian Blur
Referencehttp://en.wikipedia.org/wiki/Box_blurhttp://en.wikipedia.org/wiki/Gaussian_blurACM SIGGRAPH@UIUC Fast Image Convolutions by: Wojciech Jaroszhttp://blog.amritamaz.me/post/42203030076/understanding-box-blurhttp://tech-algorithm.com/articles/boxfiltering/