大佬教程收集整理的这篇文章主要介绍了图片滤波,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
滤波是将信号中特定波段频率滤除的操作,是抑制和防止干扰的一项重要措施。是根据观察某一随机过程的结果,对另一与之有关的随机过程进行估计的概率理论与方法。
在不考虑透明度的情况下,图片可以由
rgb
构成,如果把rgb单独抽出来,可以得到3组由(0-255)构成的数组。再把这3组数组在坐标系中显示的话,可以得到3条连续的线。通过观察线的频率,可以看出图片颜色的平滑度。如果线段斜率越小说明该线段内的颜色越平滑,反之则反差越大。
滤波这种术语,一般会用在音频处理上,通过修改音频的频率从而达到修改声音的表现。例如AudioContext就有提供滤波函数createBiquadFilter
,其内部提供了一系列的滤波算法,例如高通滤波highpass
,低通滤波lowpass
。所以我们可以利用它的api去处理图片。
从上图可以看出曲线波动的地方就是图片边缘处,色差越大,波动越大。
这里对卷积的理解有点抽象,所以直接跳过
用一个模板和一幅图像进行卷积,对于图像上的一个点,让模板的原点和该点重合,然后模板上的点和图像上对应的点相乘,然后各点的积相加,就得到了该点的卷积值。对图像上的每个点都这样处理。由于大多数模板都是对称的,所以模板不旋转。卷积是一种积分运算,用来求两个曲线重叠区域面积。可以看作加权求和,可以用来消除噪声、特征增强。
卷积核一般为奇数宽高的矩阵,一般为33,55。矩阵越大计算量越大
function convolution (pixels:ImageData, weights:number[]) {
const side = Math.round(R_356_11845@ath.sqrt(weights.length))
const halfSide = Math.floor(side / 2)
const src = pixels.data
const canvasWidth = pixels.width
const canvasHeight = pixels.height
const temporaryCanvas = document.createElement('canvas')
const temporaryCtx = temporaryCanvas.getContext('2d')!
const outputData = temporaryCtx.createImageData(canvasWidth, canvasHeight)
for (let y = 0; y < canvasHeight; y++) {
for (let x = 0; x < canvasWidth; x++) {
const dstOff = (y * canvasWidth + X) * 4
let sumReds = 0
let sumGreens = 0
let sumBlues = 0
for (let kernelY = 0; kernelY < side; kernelY++) {
for (let kernelX = 0; kernelX < side; kernelX++) {
const currentKernelY = y + kernelY - halfSide
const currentKernelX = x + kernelX - halfSide
if (currentKernelY >= 0 &&
currentKernelY < canvasHeight &&
currentKernelX >= 0 &&
currentKernelX < canvasWidth) {
const offset = (currentKernelY * canvasWidth + currentKernelX) * 4
const weight = weights[kernelY * side + kernelX]
sumReds += src[offset] * weight
sumGreens += src[offset + 1] * weight
sumBlues += src[offset + 2] * weight
}
}
}
outputData.data[dstOff] = sumReds
outputData.data[dstOff + 1] = sumGreens
outputData.data[dstOff + 2] = sumBlues
outputData.data[dstOff + 3] = 255
}
}
return outputData
}
低通滤波去掉了高频信息,即细节信息,留下的低频信息代表了概貌。常用的例子,比如美图秀秀的磨皮,去掉了脸部细节信息(痘坑,痘印,暗斑等)。
高通滤波会过滤低频信息,保留高频信息。上面我们说过斜率越高说明颜色差异越大这里往往是图片边缘部分,也表示频率越高。所以只保留高频信号的话,说明只保留了图片的边缘部分。所以高通滤波往往用做边缘处理。
const weights = [
1/9, 1/9, 1/9,
1/9, 1/9, 1/9,
1/9, 1/9, 1/9,
]
从上面的卷积核可以看出该卷积核的值之和为1,所以的目标是将目标像素点的值取周围的平均数,所以用该卷积核处理图片的结果会是模糊该图片,不过因为使用的是均值,所以图片不会很自然。一般使用高斯模糊滤波用作处理图片模糊。
高斯模糊就是在均值滤波的基础上使用正态分布,通俗讲就是9宫格内的数值之和还是1,不过它们不是简单的均分了而是具有权重。越靠近中心的值会越大,所以高斯模糊相对均值模糊会和原图更加贴切。
正态分布的二维函数如下图:
根据上面的公式可推导出的高斯矩阵方法:
function createGaussWeights (radius:number, sigma:number) {
const gaussmatrix = []
let gaussSum = 0
radius = Math.floor(radius) || 3
sigma = sigma || radius / 3
const a = 1 / 2 * Math.PI * (sigma ** 2)
const b = -1 / (2 * (sigma ** 2))
let i = 0
// 生成高斯矩阵
for (let y = radius; y >= -radius; y--) {
for (let x = -radius; x <= radius; x++) {
const g = a * Math.exp(b * (x ** 2 + y ** 2))
gaussmatrix[i++] = g
gaussSum += g
}
}
// 归一化
for (let i = 0, len = gaussmatrix.length; i < len; i++) {
gaussmatrix[i] /= gaussSum
}
return gaussmatrix
}
下图是3*3,模糊半径1.5的高斯模糊矩阵
这里高斯模糊和均值滤波都属于低通滤波,为什么呢? 因为它们的本质就是将目标像素取周围像素的平均值,所以边缘的差异性会降低。我们上面说过频率越高说明颜色差异越大,反过来颜色差异降低的话,频率也就降低了,相当于过滤了高频部分了。让图片更加平滑
const weights = [
-1, -1, -1,
-1, 8, -1,
-1, -1, -1,
]
这个是高通滤波的卷积核,可以看出是中间为正数,其余8个为-1,它们之和为0,经过该滤波器,可以看出如果中间的值比四周的大,则会得到放大期和周围的差值,相反比四周的小的话,则得到的是负数,即黑色。这样就会得到图片的边缘图。
const weights = [
0, -1, 0,
-1, 4, -1,
0, -1, 0,
]
拉普拉斯滤波也属于高通滤波,不过它比较的像素点是上下左右四个,不过最终还是能得到图片的边缘效果
操作步骤如下
// 浮雕滤波器
[
-1, -1, 0,
-1, 0, 1,
0, 1, 1
]
// 运动模糊
[
1/3, 0, 0,
0, 1/3, 0,
0, 0, 1/3,
]
以上是大佬教程为你收集整理的图片滤波全部内容,希望文章能够帮你解决图片滤波所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。