Metal每日分享,均值模糊滤镜效果

简介: Metal每日分享,均值模糊滤镜效果

Demo

  • HarbethDemo地址
  • iDay每日分享文档地址

实操代码

// 均值模糊效果滤镜
let filter = C7MeanBlur.init(radius: 0.5)
// 方案1:
let dest = BoxxIO.init(element: originImage, filter: filter)
ImageView.image = try? dest.output()
dest.filters.forEach {
    NSLog("%@", "\($0.parameterDescription)")
}
// 方案2:
ImageView.image = try? originImage.make(filter: filter)
// 方案3:
ImageView.image = originImage ->> filter


实现原理

过滤器

这款滤镜采用并行计算编码器设计.compute(kernel: "C7MeanBlur"),参数因子[radius]

对外开放参数

radius: 调整模糊半径,其实就是调整模糊度。

/// 均值模糊效果
public struct C7MeanBlur: C7FilterProtocol {
    public var radius: Float = 1
    public var modifier: Modifier {
        return .compute(kernel: "C7MeanBlur")
    }
    public var factors: [Float] {
        return [radius]
    }
    public init(radius: Float = 1) {
        self.radius = radius
    }
}

着色器

对坐标点归一化处理,将颗粒半径缩小百倍,取像素点周边上下左右半径点像素,然后将4个像素点叠加合成以达到模糊效果;

kernel void C7MeanBlur(texture2d<half, access::write> outputTexture [[texture(0)]],
                       texture2d<half, access::sample> inputTexture [[texture(1)]],
                       constant float *blurRadius [[buffer(0)]],
                       uint2 grid [[thread_position_in_grid]]) {
    constexpr sampler quadSampler(mag_filter::linear, min_filter::linear);
    const float2 coordinate = float2(float(grid.x) / outputTexture.get_width(), float(grid.y) / outputTexture.get_height());
    const half radius = half(*blurRadius) / 100.0h;
    const half4 sample1 = inputTexture.sample(quadSampler, float2(coordinate.x - radius, coordinate.y - radius));
    const half4 sample2 = inputTexture.sample(quadSampler, float2(coordinate.x + radius, coordinate.y + radius));
    const half4 sample3 = inputTexture.sample(quadSampler, float2(coordinate.x + radius, coordinate.y - radius));
    const half4 sample4 = inputTexture.sample(quadSampler, float2(coordinate.x - radius, coordinate.y + radius));
    const half4 outColor = (sample1 + sample2 + sample3 + sample4) / 4.0h;
    outputTexture.write(outColor, grid);
}


理论


平滑/模糊(Smooth/Blur)是图像处理中最简单和常用的操作,可以给图像预处理时候降低噪声。

图像平滑处理往往使图像中的边界、轮廓变得模糊,原因是因为图像受到了平均或积分运算,从频率域来考虑,图像模糊的实质是因为其高频分量被衰减

1.png

f(i,j)表示一幅图像,第i行j列的像素,h(k,l)是卷积核/卷积算子,k l大小又叫窗口大小,在k l范围内f(i,j)与h(k,l)乘积,各值相加得到一新像素值,输出图像g(i,j)

1.png

卷积过程:6x6上面是个3x3的窗口,从左向右,从上向下移动,黄色的每个像个像素点值之和取平均值赋给中心红色像素作为它卷积处理之后新的像素值。每次移动一个像素格。

滤波处理分为两大类:线性滤波和非线性滤波

线性滤波:方框滤波、均值滤波、高斯滤波

非线性滤波:中值滤波、双边滤波


Harbeth功能清单


支持ios系统和macOS系统

支持运算符函数式操作

支持多种模式数据源 UIImage, CIImage, CGImage, CMSampleBuffer, CVPixelBuffer.

支持快速设计滤镜

支持合并多种滤镜效果

支持输出源的快速扩展

支持相机采集特效

支持视频添加滤镜特效

支持矩阵卷积

支持使用系统 MetalPerformanceShaders.

支持兼容 CoreImage.

滤镜部分大致分为以下几个模块:

Blend:图像融合技术

Blur:模糊效果

Pixel:图像的基本像素颜色处理

Effect:效果处理

Lookup:查找表过滤器

Matrix: 矩阵卷积滤波器

Shape:图像形状大小相关

Visual: 视觉动态特效

MPS: 系统 MetalPerformanceShaders.


最后


关于均值模糊效果滤镜介绍与设计到此为止吧。

慢慢再补充其他相关滤镜,喜欢就给我点个星🌟吧。

滤镜Demo地址,目前包含100+种滤镜,同时也支持CoreImage混合使用。

再附上一个开发加速库KJCategoriesDemo地址

再附上一个网络基础库RxNetworksDemo地址

喜欢的老板们可以点个星🌟,谢谢各位老板!!!✌️.

相关文章
|
Java 应用服务中间件
idea tomcat 404 无法自动打开本地项目war包路径
idea tomcat 404 无法自动打开本地项目war包路径
385 0
|
存储 JavaScript 前端开发
Vue2+Vue3基础入门到实战项目(七)—— 智慧商城 项目
Vue2+Vue3基础入门到实战项目(七)—— 智慧商城 项目
618 0
|
存储 人工智能 弹性计算
着眼未来,共建多元化的大模型生态
本文介绍了德勤中国如何利用大模型赋能企业,分享了阿里云“产品博士”作为首个内部案例的成功经验,以及阿里云智能集团如何通过“模型+应用”双轮驱动,构建全面开放的大模型生态,帮助企业实现业务价值。
|
存储 监控 NoSQL
【赵渝强老师】Redis的RDB数据持久化
Redis 是内存数据库,提供数据持久化功能以防止服务器进程退出导致数据丢失。Redis 支持 RDB 和 AOF 两种持久化方式,其中 RDB 是默认的持久化方式。RDB 通过在指定时间间隔内将内存中的数据快照写入磁盘,确保数据的安全性和恢复能力。RDB 持久化机制包括创建子进程、将数据写入临时文件并替换旧文件等步骤。优点包括适合大规模数据恢复和低数据完整性要求的场景,但也有数据完整性和一致性较低及备份时占用内存的缺点。
470 6
|
设计模式 测试技术 Go
学习Go语言
【10月更文挑战第25天】学习Go语言
208 4
|
存储 消息中间件 Cloud Native
饿了么EMonitor演进史
可观测性作为技术体系的核心环节之一,跟随饿了么技术的飞速发展,不断自我革新。
8065 105
饿了么EMonitor演进史
Echarts案例:整一个炫酷一点的仪表盘
Echarts案例:整一个炫酷一点的仪表盘
1417 1
Echarts案例:整一个炫酷一点的仪表盘
|
前端开发 Java API
springboot 集成swagger
springboot 集成swagger
252 0
|
计算机视觉
【opencv】cv2.error: OpenCV(4.5.5) :-1: error: (-5:Bad argument) in function ‘imshow‘
【opencv】cv2.error: OpenCV(4.5.5) :-1: error: (-5:Bad argument) in function ‘imshow‘
1205 0
【opencv】cv2.error: OpenCV(4.5.5) :-1: error: (-5:Bad argument) in function ‘imshow‘