写在前面: 本文篇幅较长,用了大量图与公式辅佐大家深化了解各种边沿检测算子,测试编译器为 Matlab,作为入门 计算机视觉(Computer vision)范畴来说,Matlab是一款十分友好且简单的工具,其中自带各种先进的库函数,完成起来十分快速,倾向于实验性质的应用。 一.前言 首先我们先来简单了解一下 什么是数字图像处置(Digital Image Processing),先看一下数字图像主要的两个应用范畴: 1.改善图示信息以便人们解释; 2.为存储、传输和表示而对图像数据中止处置,以便于机器自动了解 我们能够简单了解为就将一幅原始图像,运用计算机处置为更为我们所能了解或所需求的方式,如图1-1所示,为基于边沿检测的免疫细胞图像自动分割过程表示图
图 1-1 克隆细胞图像自动分割过程表示图
图2 -2 车牌检测 OK,在我们大致了解了数字图像处置之后,接下来引见数字图像处置一些基本的算法。 二.数字图像处置基础学问与算法 接下来先简单引见一下一些学习数字图像处置的基础学问与算法 1).数字图像 数字图像指的是往常的图像都是以二维数字表示,每个像素的灰度值均由一个数字表示,范围为0-255(2^8) 2).二值图像、灰度图像、彩色图像 二值图像(Binary Image):图像中每个像素的灰度值仅可取 0或1,即不是取黑,就是取白,二值图像可了解为黑白图像 灰度图像(Gray Scale Image):图像中每个像素能够由 0-255的灰度值表示,细致表示为从全黑到全白中间有255个介于中间的灰色值能够取 彩色图像(Color Image):每幅图像是由 三幅灰度图像组合而成,依次表示红绿蓝三通道的灰度值,即我们熟知的RGB,此时彩色图像要视为 三维的[height,width, 3] 下面用一张图来感受一下灰度图与彩色图像之间的联络与差别
图2 -1 RGB图像的合成 其中还有一个很重要的公式,即 彩色图像转为灰度图的计算公式: G Gray表示灰度图像,RGB则表示彩色图像的红(red)、绿(green)、蓝(blue)三通道灰度值 3).邻接性、连通性 4邻域:假定有一点像素p坐标为(x, y),则它的4范畴是(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1) D邻域:假定有一点像素p坐标为(x, y), 则它的D范畴是(x + 1, y + 1), ( x + 1, y - 1), (x - 1, y + 1) (x - 1, y - 1) 8邻域:将4范畴与D范畴的汇合取并集,即表示为8邻域 图2 - 2 4邻域(左)、 D邻域(中)、 8邻域(右) 4连通:关于在像素点p的4邻域内的像素均与像素点p构成4连通 8连通:关于在像素点p的8邻域内的像素均与像素点p构成8连通 4).滤波 滤波的目的主要两个: 1.经过滤波来提取图像特征,简化图像所带的信息作为后续其它的图像处置 2.为顺应图像处置的需求,经过滤波消弭图像数字化时所混入的噪声 其中第一点就是边沿检测中所运用的基本思想,即简化图像信息,运用边沿线代表图像所携带信息 滤波可了解为滤波器(通常为3*3、5*5矩阵)在图像上中止从上到下,从左到右的遍历,计算滤波器与对应像素的值并依据滤波目的中止数值计算返回值到当前像素点,如图 2-3所示,蓝色块表示滤波器,对图像中止点积运算并赋值到图像 细致公式表示为: (其中 表示当前像素点, 表示当前像素与滤波器对应值相乘的值,n为滤波器大小,举例来说如若此滤波器值全为1,则此公式计算的是当前像素点的8连通像素点的平均值,因而滤波完后的图像应表示为 含糊的效果,含糊水平取决于滤波器的大小,滤波器大小(size)越大,含糊效果越明显)
三.边沿检测(Sobel、Prewitt、Roberts、Canny、Marr-Hildreth)1.基本边沿检测算子 在引见完滤波的学问后,学习基本边沿检测算法是一件很轻松的事情,由于边沿检测实质上就是一种滤波算法,区别在于 滤波器的选择,滤波的规则是完整分歧的 为了更好了解边沿检测算子,我们引入 梯度(gradient)这一概念,梯度是 人工智能(artificial intelligence)十分重要的一个概念,遍布 机器学习、 深度学习范畴,学过微积分的同窗应该知道一维函数的一阶微分基本定义为: 而我们刚才也提到了,图像的滤波普通是 基于灰度图中止的,因而图像此时是二维的,因而我们在看一下二维函数的微分,即偏微分方程:
由上面的公式我们能够看到,图像梯度即当前所在像素点关于X轴、Y轴的 偏导数,所以梯度在图像处置范畴我们能够也了解为像素灰度值 变更的速度,下面我们举一个简单的例子:
图 3-1 图中我们能够看到,100与90之间相差的灰度值为10,即当前像素点在X轴方向上的梯度为10,而其它点均为90,则求导后发现梯度全为0,因而我们能够发往常数字图像处置,因其像素性质的特殊性,微积分在图像处置表示的方式为计算当前像素点沿偏微分方向的差值,所以实践的应用是不需求用到求导的, 只需中止简单的加减运算 而另一个概念 梯度的模则表示f(x, y),在其最大变更率方向上的单位距离所增加的量,即: 在了解完梯度的概念之后呢,下面我们先引见一下几种基本边沿检测滤波器: Sobel、Prewitt、Roberts算子
图 3-2 Roberts算子
图 3-2 Prewitt算子图 3-3 Sobel算子 我们以Sobel为例,其中 分别表示关于X轴、Y轴的边沿检测算子,从 算子结构能够很分明发现,这个滤波器是计算当前像素点右边与左边8连通像素灰度值的差值,我们先经过一维的概念来了解一下: 如往常有一个一维数组长度为10,值为: [ 8, 6, 2, 4, 9, 1, 3, 5, 10, 6 ] 此时我们的一维边沿检测算子则表示为[ -1, 0, 1 ],往常我们把边沿检测算子放在数组上面中止点积(即对应点相乘之后的和),得到结果为: [ 6, -6, -2, 7, -3, -6, 4, 7, 1, -10] 能够发现得到的值呈现了负数,但我们之前的定义则声明了像素灰度值 定义域为0-255范围内,因而这里普通的操作为 将负数截断到0-255以内或者直接取绝对值,因而往常我们得到的是 [ 6, 6, 2, 7, 3, 6, 4, 7, 1, 10] 其中数字的大小则表示了当前像素点梯度的模大小,即灰度变更的速度有多大,值越大,我们一定水平上就能够确信当前点为我们所要找的边沿点,经过一维的例子我们能够更好了解二维的边沿检测思想,即沿着X轴、Y轴中止两次滤波操作,得到的结果中止平方求和加根号的操作得出当前像素点的 图像梯度,我们来经过一张图了解一下这个过程: 图 3-4 原图像、沿X轴梯度图像、沿Y轴梯度图像、梯度图像的可视化 图中(a)为原始的灰度图像,(b)和(c)为运用图3-3中Sobel算子的 、 两种方式分别对原始图像中止的滤波结果,即表示为 分别沿X、Y轴的梯度图,最后将两个图融合在一同则得到了我们所需的梯度图像(d),在给大家一张图来辅佐了解Sobel算法
往常我们曾经大致了解了边沿检测的基本思想了,看着图 3-4(d)是不是觉得它挺美观的呢,但是美观不一定阐明它就是我们所需求的边沿图,直接用基本的边沿算子如Sobel求得的边沿图存在很多问题,如 噪声污染没有被扫除、边沿线太过于粗宽等,因而我们接下来要引见两个先进的边沿检测算子: Canny算子和Marr-Hildreth算子 2.较为先进的边沿检测算子 1).Canny算子 Canny算子是澳洲计算机科学家约翰·坎尼(John F. Canny)于1986年开发出来的一个多级 边沿检测算法,其目的是找到一个最优的边沿,其最优边沿的定义是: 1. 好的检测--算法能够尽可能多地标示出图像中的实践边沿 2. 好的定位--标识出的边沿要与实践图像中的实践边沿尽可能接近 3. 最小响应--图像中的边沿只能标识一次,并且可能存在的图像噪声不应该标识为边沿 所以接下来我们来引见一下目前盛行的Canny算法的细致步骤 (1).高斯(Gaussian)滤波 高斯滤波目前是最为盛行的去噪滤波算法,高斯与我们学的概率论中正态散布中 正态一词指的是同一个意义,其原理为依据待滤波的像素点及其邻域点的灰度值依照高斯公式生成的参数规则中止 加权平均,这样能够有效滤去理想图像中叠加的 高频噪声(noise) 二维高斯公式为: 常见的高斯滤波器有:
图 3-5 常见的高斯滤波器 其实高斯滤波器很像一个 金字塔结构,其滤波器的值大小我们能够了解为 权重(weight),值越大对应的像素点权重越大,重量也就越大,因而从高斯滤波器我们能够看出对应当前像素点,距离越远权重越小,对灰度值的贡献也就越小 让我们举个例子来了解一下高斯滤波,如图3-5中左边的高斯滤波器,其中心点4我们能够把它看成是'主人公',其周围的点看成是'邻居',噪声我们把它看成是'坏人',往常我们假定这9个人里面,有一个人是'坏人',我们也知道坏人是肯定会说自己是大好人的,但要是我们有投票机制决议一个人能否为'坏人'呢,其中权重(weight)则对应每个人说话的重量,投票机制就为我们所说的加权平均战略,往常我们能够很直观地发现,其实高斯滤波就是一个会思索其周围像素点的滤波器,即方便前点位为噪声点,高斯滤波器也会经过周围点的灰度值来限制噪声的影响,生成高斯滤波器与滤波的代码如下: sigma=1; %高斯规范差 % 依据高斯规范差计算滤波器长度 filterExtent = ceil(4*sigma); x = -filterExtent:filterExtent; % 生成一维高斯核 c = 1/(sqrt(2*pi)*sigma); gaussKernel = c * exp(-(x.^2)/(2*sigma^2)); % 规范化 gaussKernel = gaussKernel/sum(gaussKernel); % 对图像中止高斯滤波平滑 aSmooth=imfilter(a,gaussKernel,'conv','replicate'); % 沿着X轴卷积 aSmooth=imfilter(aSmooth,gaussKernel','conv','replicate'); % 沿着Y轴卷积 (其中gaussKernel'表示对gaussKernel中止转置) (2).计算梯度图像与角度图像 计算梯度图像我们刚才基本也有了解了一下,无非就是用各种边沿检测算子中止梯度的检测,但Canny中运用的梯度检测算子有点高级,是 运用高斯滤波器中止梯度计算得到的滤波器,得到的结果也相似于Sobel算子,即 距离中心点越近的像素点权重越大,代码如下: % 数值梯度函数(Gaussian核的生成1-D导数) derivGaussKernel = gradient(gaussKernel); % 规范化 negVals = derivGaussKernel < 0; posVals = derivGaussKernel > 0; derivGaussKernel(posVals) = derivGaussKernel(posVals)/sum(derivGaussKernel(posVals)); derivGaussKernel(negVals) = derivGaussKernel(negVals)/abs(sum(derivGaussKernel(negVals))); % 计算梯度 dx = imfilter(aSmooth, derivGaussKernel, 'conv','replicate'); dy = imfilter(aSmooth, derivGaussKernel', 'conv','replicate'); mag = hypot(dx,dy); magmax = max(mag(:)); if magmax>0 magGrad = mag / magmax; % 梯度规范化 end 角度图像的计算则较为简单,其作用为非极大值抑止的方向提供指导,公式如下:
(3).对梯度图像中止非极大值抑止 从上一步得到的梯度图像存在边沿粗宽、弱边沿干扰等众多问题,往常我们能够运用 非极大值抑止来寻觅像素点 部分最大值,将非极大值所对应的灰度值 置0,这样能够剔除一大部分非边沿的像素点 如图 3-6所示,C表示为当前非极大值抑止的点,g1-4为它的8连通邻域点,图中蓝色线段表示上一步计算得到的角度图像C点的值,即梯度方向,第一步先判别C灰度值在8值邻域内能否最大,如是则继续检查图中梯度方向交点dTmp1,dTmp2值能否大于C,如C点大于dTmp1,dTmp2点的灰度值,则认定C点为极大值点,置为1,因而最后生成的图像应为一副 二值图像,边沿理想状态下都为 单像素边沿
图 3-6 非极大值抑止 (其中需求留意的是梯度方向交点并不一定落在8范畴所在8个点的位置,因而dTmp1和dTmp2实践应用中是运用相邻两个点的双线性插值所构成的灰度值) 最后在上一张图辅佐大家了解,如图3-7所示,其中梯度方向均为垂直向上,经过非极大值抑止后取梯度方向上最大值为边沿点,构成细且精确的单像素边沿
图 3-7 (4).运用双阈值中止边沿衔接 经过以上三步之后得到的边沿质量曾经很高了,但还是存在很多 伪边沿,因而Canny算法中所采用的算法为 双阈值法,细致思绪为选取两个阈值,将小于低阈值的点以为是假边沿置0,将大于高阈值的点以为是强边沿置1,介于中间的像素点需中止进一步的检查 依据高阈值图像中把边沿链接成轮廓,当抵达轮廓的端点时,该算法会在断点的8邻域点中寻觅满足低阈值的点,再依据此点搜集新的边沿,直到整个图像闭合,细致代码为: function nedge=connect1(nedge,y,x,low,high,magGrad) %种子定位后的连通剖析 neighbour=[-1 -1;-1 0;-1 1;0 -1;0 1;1 -1;1 0;1 1]; %八连通搜索 [m n]=size(nedge); for k=1:8 yy=fix(y+neighbour(k,1)); xx=fix(x+neighbour(k,2)); if yy>=1 &&yy<=m &&xx>=1 && xx<=n if magGrad(yy,xx)>=low & nedge(yy,xx)~=255 & magGrad(yy,xx)<high nedge(yy,xx)=255; %disp('check check'); %nedge=connect1(nedge,yy,xx,low,high,magGrad); end end end end 但由于寻觅弱边沿点的计算代价过大,由于运用的是递归思想,且所找寻到的弱边沿点为数未几,因而实践应用中常常舍去这一步骤,取而代之的是基于形态学的 边沿细化操作,细致思想我们以后还会提到,细致代码为: H = bwmorph(H, 'thin', 1); 至此,我们曾经深度了解了Canny算法的思想与完成伎俩,实践应用中Canny普通是边沿检测的首选项,其算法思想也十分值得我们学习,接下来我们在简单引见基于二阶导数法的 Marr-Hildreth边沿检测算子 1).Marr-Hildreth算子 在学习Marr-Hildreth算子之前我们先来了解一下为什么要用 二阶导数法 如图 3-8所示,左边表示的是一副灰度图像,从左到右从黑色(0)渐突变为白色(255),往常我们来看它的水平灰度剖面,灰度值从小到大平稳上升,其一阶导数表示为在上升区域为不变的值,其中得到的信息是图像灰度值是平稳过渡的,即梯度值相等,接下来在将其求二次导数,得到的图像为在开端过渡的起点为正数,其值为一阶导数在此点的梯度值,终了点也和起点一样,往常重点来了,我们将这两点连起来得到一个与X轴的交叉点,这一点就是我们所以为的边沿点,这就是二阶导数应用在边沿检测范畴的巧妙之处(第一次接触的时分觉得巨神奇) 在看一下marr和hildreth的证明结论: 1.灰度变更与图像尺寸无关,因而他们的检测请求运用不同尺寸的算子 2.灰度的忽然变换会在一阶导数中惹起波峰或波谷,在二阶导数中等效惹起零交叉
图 3-8 零交叉原理 学习了基于二阶导数的马尔哈希算法原理之后,我们来看一下它的思绪: (1).高斯滤波 对你没看错,还是高斯滤波,基本一切边沿检测算法前面都会加一个高斯滤波来去除高频噪声,所以这里不在多说了,大家往前回想一下就好了 (2).计算拉普拉斯(Laplacian)二阶导 Marr-Hildreth证明,最满足图像处置需求的算子是滤波器 拉普拉斯高斯(Log)算子,细致原理我们不在多做论述,这里我们来看一下它的公式: 由其生成的拉普拉斯滤波器也被称为 墨西哥草帽算子,由于其中间普通为较大的正数,8邻域连通点为较小的负数值,常用的滤波器如图 3-9所示:
图 3-9 拉普拉斯滤波器 之后就是运用拉普拉斯滤波器中止图像的滤波操作,得到待计算图像 (3).计算零交叉(Zero crossing) 零交叉的完成较为简单,由于零交叉点意味着至少两个相邻的像素点的像素值异号,一共有四种需求检测的状况:左右,上下,两个对角,其中假如滤波后的图像g(x, y)的恣意像素p处的四种状况其中一组的差值的绝对值超越了设定的 阈值,则我们能够称p为一个零交叉像素,示例如下: 图 3-10 此为Marr-Hildreth其中一小部分,检测[ - +]这一状况能否满足,其中thresh为提到的阈值 到这里我们就学习了两种最为盛行且经典的先进边沿检测算法与思想,接下来说的是一些阅历与算法的选择参考 四.弥补 1.滤波器的大小应该是 奇数,这样才有一个中心点可中止赋值操作,常见的 滤波器或 卷积核(Conv kernel) 有3*3、5*5等,因而也有了 半径的概念,例如5*5的卷积核的半径为2 2.滤波器中一切元素之 和应为0,这一限制条件是保障滤波前后图像 总体灰度值不变 3.Roberts算子、Sobel算子、Prewitt算子运算速率高,对噪声也有一定抑止作用,但检测出的边沿质量不高,如 边沿较粗、定位不准、连续点多 4.Canny算子不容易受噪声干扰,得到的边沿精密且精确,缺陷就是运算代价较高,运转于实时图像处置较艰难, 适用于高精度请求的应用 5.Marr-Hildreth算子边沿检测效果相对较优,但 关于噪声比较敏感(因其二阶运算的性质) 五.总结 总体来说, 边沿检测算法应用面十分广,提高很多范畴,是入门 计算机视觉(Computer vision)学习一个十分好的途径,其中很多思想和原理的东西至今对笔者也有印象,所以笔者第一篇文章就想着从这个开端写,还有就是文章有些中央是笔者自己的一些了解和见解,如有错误的中央希望大家辅佐指出来哈,以后还会继续写一些关于 机器学习(Machine learning)、 深度学习(Deep learning)、 人脸辨认(Face recognition)的文章,最后附上Canny边沿检测算法完好的Matlab代码完成(当然也能够调用edge函数,但是学习的话最好自己从底层完成一遍嘛是吧) I=imread('cameraman.tif'); %I=rgb2gray(I); figure(1);subplot(121);imshow(I);xlabel('原图像'); [m n]=size(I); a=double(I); sigma=1; %高斯规范差 %highThresh=0.0625; %上阈值 %lowThresh=0.0250 ; %下阈值 %=======================高斯滤波&梯度计算======================= %%%%%%%%%%%%%%%%%%%%%%%%%Old%%%%%%%%%%%%%%%%%%%%%%%%%%% %pw = 1:30; %ssq = sigma^2; %width = find(exp(-(pw.*pw)/(2*ssq))>0.0001,1,'last'); %if isempty(width) % width = 1; %end %t = (-width:width); %gauss = exp(-(t.*t)/(2*ssq))/(2*pi*ssq); % 一维高斯滤波器 %[x,y]=meshgrid(-width:width,-width:width); %gauss2=-x.*exp(-(x.*x+y.*y)/(2*ssq))/(pi*ssq); %二维高斯滤波器 %对图像中止高斯滤波平滑 %aSmooth=imfilter(a,gauss,'conv','replicate'); % 沿着X轴卷积 %aSmooth=imfilter(aSmooth,gauss','conv','replicate'); % 沿着Y轴卷积 %运用二维高斯对图像中止卷积 %dx = imfilter(aSmooth, gauss2, 'conv','replicate'); %dy = imfilter(aSmooth, gauss2', 'conv','replicate'); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 依据高斯规范差计算滤波器长度 filterExtent = ceil(4*sigma); x = -filterExtent:filterExtent; % 生成一维高斯核 c = 1/(sqrt(2*pi)*sigma); gaussKernel = c * exp(-(x.^2)/(2*sigma^2)); % 规范化 gaussKernel = gaussKernel/sum(gaussKernel); % 数值梯度函数(Gaussian核的生成1-D导数) derivGaussKernel = gradient(gaussKernel); % 规范化 negVals = derivGaussKernel < 0; posVals = derivGaussKernel > 0; derivGaussKernel(posVals) = derivGaussKernel(posVals)/sum(derivGaussKernel(posVals)); derivGaussKernel(negVals) = derivGaussKernel(negVals)/abs(sum(derivGaussKernel(negVals))); % 对图像中止高斯滤波平滑 aSmooth=imfilter(a,gaussKernel,'conv','replicate'); % 沿着X轴卷积 aSmooth=imfilter(aSmooth,gaussKernel','conv','replicate'); % 沿着Y轴卷积 %hv=fspecial('sobel'); % 计算梯度 dx = imfilter(aSmooth, derivGaussKernel, 'conv','replicate'); dy = imfilter(aSmooth, derivGaussKernel', 'conv','replicate'); mag = hypot(dx,dy); magmax = max(mag(:)); if magmax>0 magGrad = mag / magmax; % 梯度规范化 end % 阈值选择 %PercentOfPixelsNotEdges = 0.7; counts=imhist(magGrad, 64); highThresh = find(cumsum(counts) > 0.7*m*n, 1 ,'first' ) / 64; lowThresh = 0.4*highThresh; %figure(8);imshow(magGrad); %%========================高斯滤波======================================== %w=fspecial('gaussian',[5 5]); %img=imfilter(img,w,'replicate'); %figure; %imshow(uint8(img)) %%===================sobel边沿检测======================================= %hv=fspecial('sobel'); %dx=imfilter(img,hv,'replicate'); %求横边沿 %hh=hv'; %dy=imfilter(img,hh,'replicate'); %求竖边沿 %img=sqrt(dx.^2+dy.^2); % magmax = max(img(:));% (阈值选择归一化) % if magmax > 0 % magGrad = img / magmax; % end %figure; %imshow(uint8(img)); I = thinAndThreshold(dx, dy, magGrad, lowThresh, highThresh); %disp(lowThresh); subplot(122);imshow(I);xlabel('canny边沿检测'); disp("高阈值TL: "+highThresh); disp("低阈值TH: "+lowThresh); %========================非极大值抑止和边沿衔接======================================= function H = thinAndThreshold(dx, dy, magGrad, lowThresh, highThresh) E = cannyFindLocalMaxima(dx,dy,magGrad,lowThresh); %非极大值抑止 if ~isempty(E) [rstrong,cstrong] = find(magGrad>highThresh & E); if ~isempty(rstrong) H = bwselect(E, cstrong, rstrong, 8); % 选定强边沿8连通目的 % figure(2);imshow(H); % set(0,'RecursionLimit',1000); %弱边沿连通(无太大作用,且运算时间过长) % [xstrong ystrong]=find(magGrad>highThresh & E); % for i=1:numel(xstrong); % H = connect1(H,xstrong(i),ystrong(i),lowThresh,highThresh,magGrad); % end % figure(3);imshow(H); H = bwmorph(H, 'thin', 1); % 边沿细化 else H = false(size(E)); end else H = false(size(E)); end end %========================弱边沿衔接======================================= function nedge=connect1(nedge,y,x,low,high,magGrad) %种子定位后的连通剖析 neighbour=[-1 -1;-1 0;-1 1;0 -1;0 1;1 -1;1 0;1 1]; %八连通搜索 [m n]=size(nedge); for k=1:8 yy=fix(y+neighbour(k,1)); xx=fix(x+neighbour(k,2)); if yy>=1 &&yy<=m &&xx>=1 && xx<=n if magGrad(yy,xx)>=low & nedge(yy,xx)~=255 & magGrad(yy,xx)<high nedge(yy,xx)=255; %disp('check check'); %nedge=connect1(nedge,yy,xx,low,high,magGrad); end end end end 效果如图所示:
本文亮点总结 1.边沿检测算法,其目的是找到一个最优的边沿,其最优边沿的定义是: 1.好的检测 --算法能够尽可能多地标示出图像中的实践边沿 2.好的定位 --标识出的边沿要与实践图像中的实践边沿尽可能接近 3.最小响应 --图像中的边沿只能标识一次,并且可能存在的图像噪声不应该标识为边沿 2.高斯滤波目前是最为盛行的去噪滤波算法,高斯与我们学的概率论中正态散布中正态一词指的是同一个意义,其原理为依据待滤波的像素点及其邻域点的灰度值依照高斯公式生成的参数规则中止加权平均,这样能够有效滤去理想图像中叠加的高频噪声(noise)。 转自:极市平台 作者:Rustle@知乎 https://zhuanlan.zhihu.com/p/59640437 本文仅作技术信息交流,如有侵权,请联络删除。 end |
万奢网手机版
官网微博:万奢网服务平台