大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
在图像处理以及图像特效中,经常会用到一种成高斯分布的蒙版,蒙版可以用来做图像融合,将不同内容的两张图像结合蒙版,可以营造不同的艺术效果。
创新互联建站专注于海西企业网站建设,成都响应式网站建设公司,商城网站建设。海西网站建设公司,为海西等地区提供建站服务。全流程按需策划设计,专业设计,全程项目跟踪,创新互联建站专业和态度为您提供的服务
I=M∗F+(1−M)∗B
这里I 表示合成后的图像,F 表示前景图,B 表示背景图,M 表示蒙版,或者直接用 蒙版与图像相乘, 形成一种渐变映射的效果。如下所示。
I=M∗F
这里介绍一下高斯分布蒙版的特性,并且用Python实现。
高斯分布的蒙版,简单来说,就是一个从中心扩散的亮度分布图,如下所示:
亮度的范围从 1 到 0, 从中心到边缘逐渐减弱,中心的亮度值最高为1,边缘的亮度值最低为 0. 图像上任何一点的亮度值为:
G(i,j)=exp−d2R
其中 i,j 表示图像上任何一点的坐标,以左上角为坐标原点,d 表示 图像上任何一点 到图像中心点的距离,R 表示图像的半径。假设图像的高为 H 宽为 W
R=(H/2)2+(W/2)2−−−−−−−−−−−−−−√=12H2+W2−−−−−−−−√
d=(i−H/2)2+(j−W/2)2−−−−−−−−−−−−−−−−−−−√
IMAGE_WIDTH = 512IMAGE_HEIGHT = 392center_x = IMAGE_WIDTH/2center_y = IMAGE_HEIGHT/2R = np.sqrt(center_x**2 + center_y**2)Gauss_map = np.zeros((IMAGE_HEIGHT, IMAGE_WIDTH))# 利用 for 循环 实现for i in range(IMAGE_HEIGHT):
for j in range(IMAGE_WIDTH):
dis = np.sqrt((i-center_y)**2+(j-center_x)**2)
Gauss_map[i, j] = np.exp(-0.5*dis/R)# 直接利用矩阵运算实现mask_x = np.matlib.repmat(center_x, IMAGE_HEIGHT, IMAGE_WIDTH)mask_y = np.matlib.repmat(center_y, IMAGE_HEIGHT, IMAGE_WIDTH)x1 = np.arange(IMAGE_WIDTH)x_map = np.matlib.repmat(x1, IMAGE_HEIGHT, 1)y1 = np.arange(IMAGE_HEIGHT)y_map = np.matlib.repmat(y1, IMAGE_WIDTH, 1)y_map = np.transpose(y_map)Gauss_map = np.sqrt((x_map-mask_x)**2+(y_map-mask_y)**2)Gauss_map = np.exp(-0.5*Gauss_map/R)# 显示和保存生成的图像plt.figure()
plt.imshow(Gauss_map, plt.cm.gray)
plt.imsave('out_2.jpg', Gauss_map, cmap=plt.cm.gray)
plt.show()
高斯分布(Gaussian distribution)又名正态分布(Normal distribution),是一个在数学、物理及工程等领域都非常重要的概率分布,在统计学的许多方面有着重大的影响力。若随机变量X服从一个数学期望为μ、方差为σ^2的高斯分布,记为N(μ,σ^2)。其概率密度函数为正态分布的期望值μ决定了其位置,其标准差σ决定了分布的幅度。因其曲线呈钟形,因此人们又经常称之为钟形曲线。我们通常所说的标准正态分布是μ = 0,σ = 1的正态分布。
多元是指样本以多个变量来描述,或具有多个属性,在此一般用d维特征向量表示,X=[x1,…,xd]T。d维特征向量的正态分布用下式表示
(2-32)
其中μ是X的均值向量,也是d维,
μ=E{X}=[μ1,μ2,…,μd]T (2-33)
Σ是d×d维协方差矩阵,而Σ-1是Σ的逆矩阵,|Σ|是Σ的行列式
Σ=E{(X-μ)(X-μ)T} (2-34)
Σ是非负矩阵,在此我们只考虑正定阵,即|Σ|>0。
多元正态分布与单态量正态分布在形式上尽管不同,但有很多相似之处,实际上单变量正态分布只是维数为1的多元分布。当d=1时,Σ只是一个1×1的矩阵,也就是只有1个元素的矩阵,退化成一个数,|Σ|1/2也就是标准差σ,Σ-1也就是σ-2,而(X-μ)T(X-μ)也变成(X-μ)2,因此(2-32)也就演变成(2-29)。但是多元正态分布要比单变量时复杂得多,具有许多重要的特性,下面只就有关的特性加以简单叙述。
borderType= None)函数
此函数利用高斯滤波器平滑一张图像。该函数将源图像与指定的高斯核进行卷积。
src:输入图像
ksize:(核的宽度,核的高度),输入高斯核的尺寸,核的宽高都必须是正奇数。否则,将会从参数sigma中计算得到。
dst:输出图像,尺寸与输入图像一致。
sigmaX:高斯核在X方向上的标准差。
sigmaY:高斯核在Y方向上的标准差。默认为None,如果sigmaY=0,则它将被设置为与sigmaX相等的值。如果这两者都为0,则它们的值会从ksize中计算得到。计算公式为:
borderType:像素外推法,默认为None(参考官方文档 BorderTypes
)
在图像处理中,高斯滤波主要有两种方式:
1.窗口滑动卷积
2.傅里叶变换
在此主要利用窗口滑动卷积。其中二维高斯函数公式为:
根据上述公式,生成一个3x3的高斯核,其中最重要的参数就是标准差 ,标准差 越大,核中心的值与周围的值差距越小,曲线越平滑。标准差 越小,核中心的值与周围的值差距越大,曲线越陡峭。
从图像的角度来说,高斯核的标准差 越大,平滑效果越不明显。高斯核的标准差 越小,平滑效果越明显。
可见,标准差 越大,图像平滑程度越大
参考博客1:关于GaussianBlur函数
参考博客2:关于高斯核运算
本文翻译自
上一节中探讨的k-means聚类模型简单易懂,但其简单性导致其应用中存在实际挑战。具体而言,k-means的非概率特性及简单地计算点与类蔟中心的欧式距离来判定归属,会导致其在许多真实的场景中性能较差。本节,我们将探讨高斯混合模型(GMMs),其可以看成k-means的延伸,更可以看成一个强有力的估计工具,而不仅仅是聚类。
我们将以一个标准的import开始
我们看下k-means的缺陷,思考下如何提高聚类模型。正如上一节所示,给定简单,易于分类的数据,k-means能找到合适的聚类结果。
举例而言,假设我们有些简单的数据点,k-means算法能以某种方式很快地将它们聚类,跟我们肉眼分辨的结果很接近:
从直观的角度来看,我可能期望聚类分配时,某些点比其他的更确定:举例而言,中间两个聚类之间似乎存在非常轻微的重叠,这样我们可能对这些数据点的分配没有完全的信心。不幸的是,k-means模型没有聚类分配的概率或不确定性的内在度量(尽管可能使用bootstrap 的方式来估计这种不确定性)。为此,我们必须考虑泛化这种模型。
k-means模型的一种理解思路是,它在每个类蔟的中心放置了一个圈(或者,更高维度超球面),其半径由聚类中最远的点确定。该半径充当训练集中聚类分配的一个硬截断:任何圈外的数据点不被视为该类的成员。我们可以使用以下函数可视化这个聚类模型:
观察k-means的一个重要发现,这些聚类模式必须是圆形的。k-means没有内置的方法来计算椭圆形或椭圆形的簇。因此,举例而言,假设我们将相同的数据点作变换,这种聚类分配方式最终变得混乱:
高斯混合模型(GMM)试图找到一个多维高斯概率分布的混合,以模拟任何输入数据集。在最简单的情况下,GMM可用于以与k-means相同的方式聚类。
但因为GMM包含概率模型,因此可以找到聚类分配的概率方式 - 在Scikit-Learn中,通过调用predict_proba方法实现。它将返回一个大小为[n_samples, n_clusters]的矩阵,用于衡量每个点属于给定类别的概率:
我们可以可视化这种不确定性,比如每个点的大小与预测的确定性成比例;如下图,我们可以看到正是群集之间边界处的点反映了群集分配的不确定性:
本质上说,高斯混合模型与k-means非常相似:它使用期望-最大化的方式,定性地执行以下操作:
有了这个,我们可以看看四成分的GMM为我们的初始数据提供了什么:
同样,我们可以使用GMM方法来拟合我们的拉伸数据集;允许full的协方差,该模型甚至可以适应非常椭圆形,伸展的聚类模式:
这清楚地表明GMM解决了以前遇到的k-means的两个主要实际问题。
如果看了之前拟合的细节,你将看到covariance_type选项在每个中都设置不同。该超参数控制每个类簇的形状的自由度;对于任意给定的问题,必须仔细设置。默认值为covariance_type =“diag”,这意味着可以独立设置沿每个维度的类蔟大小,并将得到的椭圆约束为与轴对齐。一个稍微简单和快速的模型是covariance_type =“spherical”,它约束了类簇的形状,使得所有维度都相等。尽管它并不完全等效,其产生的聚类将具有与k均值相似的特征。更复杂且计算量更大的模型(特别是随着维数的增长)是使用covariance_type =“full”,这允许将每个簇建模为具有任意方向的椭圆。
对于一个类蔟,下图我们可以看到这三个选项的可视化表示:
尽管GMM通常被归类为聚类算法,但从根本上说它是一种密度估算算法。也就是说,GMM适合某些数据的结果在技术上不是聚类模型,而是描述数据分布的生成概率模型。
例如,考虑一下Scikit-Learn的make_moons函数生成的一些数据:
如果我们尝试用视为聚类模型的双成分的GMM模拟数据,则结果不是特别有用:
但是如果我们使用更多成分的GMM模型,并忽视聚类的类别,我们会发现更接近输入数据的拟合:
这里,16个高斯分布的混合不是为了找到分离的数据簇,而是为了对输入数据的整体分布进行建模。这是分布的一个生成模型,这意味着GMM为我们提供了生成与我们的输入类似分布的新随机数据的方法。例如,以下是从这个16分量GMM拟合到我们原始数据的400个新点:
GMM非常方便,可以灵活地建模任意多维数据分布。
GMM是一种生成模型这一事实为我们提供了一种确定给定数据集的最佳组件数的自然方法。生成模型本质上是数据集的概率分布,因此我们可以简单地评估模型下数据的可能性,使用交叉验证来避免过度拟合。校正过度拟合的另一种方法是使用一些分析标准来调整模型可能性,例如 Akaike information criterion (AIC) 或 Bayesian information criterion (BIC) 。Scikit-Learn的GMM估计器实际上包含计算这两者的内置方法,因此在这种方法上操作非常容易。
让我们看看在moon数据集中,使用AIC和BIC函数确定GMM组件数量:
最佳的聚类数目是使得AIC或BIC最小化的值,具体取决于我们希望使用的近似值。 AIC告诉我们,我们上面选择的16个组件可能太多了:大约8-12个组件可能是更好的选择。与此类问题一样,BIC建议使用更简单的模型。
注意重点:这个组件数量的选择衡量GMM作为密度估算器的效果,而不是它作为聚类算法的效果。我鼓励您将GMM主要视为密度估算器,并且只有在简单数据集中保证时才将其用于聚类。
我们刚刚看到了一个使用GMM作为数据生成模型的简单示例,以便根据输入数据定义的分布创建新样本。在这里,我们将运行这个想法,并从我们以前使用过的标准数字语料库中生成新的手写数字。
首先,让我们使用Scikit-Learn的数据工具加载数字数据:
接下来让我们绘制前100个,以准确回忆我们正在看的内容:
我们有64个维度的近1,800位数字,我们可以在这些位置上构建GMM以产生更多。 GMM可能难以在如此高维空间中收敛,因此我们将从数据上的可逆维数减少算法开始。在这里,我们将使用一个简单的PCA,要求它保留99%的预测数据方差:
结果是41个维度,减少了近1/3,几乎没有信息丢失。根据这些预测数据,让我们使用AIC来计算我们应该使用的GMM组件的数量:
似乎大约110个components最小化了AIC;我们将使用这个模型。我们迅速将其与数据拟合并确保它已收敛合:
现在我们可以使用GMM作为生成模型在这个41维投影空间内绘制100个新点的样本:
最后,我们可以使用PCA对象的逆变换来构造新的数字:
大部分结果看起来像数据集中合理的数字!
考虑一下我们在这里做了什么:给定一个手写数字的样本,我们已经模拟了数据的分布,这样我们就可以从数据中生成全新的数字样本:这些是“手写数字”,不是单独的出现在原始数据集中,而是捕获混合模型建模的输入数据的一般特征。这种数字生成模型可以证明作为贝叶斯生成分类器的一个组成部分非常有用,我们将在下一节中看到。
clear
close all
%%%%%%%%%%%%%%%%%%%%%%%%%生成实验数据集
rand('state',0)
sigma_matrix1=eye(2);
sigma_matrix2=50*eye(2);
u1=[0,0];
u2=[30,30];
m1=100;
m2=300;%样本数
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%sm1数据集
Y1=multivrandn(u1,m1,sigma_matrix1);
Y2=multivrandn(u2,m2,sigma_matrix2);
scatter(Y1(:,1),Y1(:,2),'bo')
hold on
scatter(Y2(:,1),Y2(:,2),'r*')
title('SM1数据集')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%sm2数据集
u11=[0,0];
u22=[5,5];
u33=[10,10];
u44=[15,15];
m=600;
sigma_matrix3=2*eye(2);
Y11=multivrandn(u11,m,sigma_matrix3);
Y22=multivrandn(u22,m,sigma_matrix3);
Y33=multivrandn(u33,m,sigma_matrix3);
Y44=multivrandn(u44,m,sigma_matrix3);
figure(2)
scatter(Y11(:,1),Y11(:,2),'bo')
hold on
scatter(Y22(:,1),Y22(:,2),'r*')
scatter(Y33(:,1),Y33(:,2),'go')
scatter(Y44(:,1),Y44(:,2),'c*')
title('SM2数据集')
end
function Y = multivrandn(u,m,sigma_matrix)
%%生成指定均值和协方差矩阵的高斯数据
n=length(u);
c = chol(sigma_matrix);
X=randn(m,n);
Y=X*c+ones(m,1)*u;
end
GDA方法与Logistic方法的主要区别在于这两个模型的假设不同:GDA方法假设p(x|y)服从多元高斯分布,并且输入特征是连续的;Logistic方法并没有GDA那么强的假设,它既没有要求p(x|y)服从多元高斯分布,也没有要求输入特征是连续的。因此Logistic的适用范围比GDA更加广泛。例如:如果输入特征符合泊松分布,则Logistic得到的结果会比GDA更加准确。如果输入特征满足GDA的要求时,既可以用Logistic方法也可以用GDA,但是在这种情况下GDA得到的结果会比Logistic方法得到的结果准确些。下面给出GDA和Logistic方法的简要说明,最后给出相应的 python代码。
GDA是一种生成学习法,主要利用贝叶斯准则得到后验分布律,然后通过最大后验分布对输入数据进行分类。简单地说,也就是在给定某个特征情况下,拥有此特征的数据属于哪个类的概率大 就属于哪个类。GDA的优势:由于有高斯分布的先验信息,如果确实符合实际数据,则只需要少量的样本就可以得到较好的模型。
Logistic是一种判别想学习法,判别学习法通过建立输入数据与输出信息之间的映射关系学得p(y|x),这个与生成学习法是不同的。在生成学习法中首先要确定p(x|y)和p(y)。Logistic主要是通过sigmoid函数来确定输入数据及是将如何进行分类的。Logistic的优势:具有更高的鲁棒性和对数据的分布不明感(不想GDA那样需要特征服从高斯分布)。
下面是具体的python代码:
一、GDA模型的python代码:
点击(此处)折叠或打开
def GDA(dataIn, classLabel):
m = len(classLabel);
sum_1 = sum(classLabel);
q = sum_1/(float(m));
notLabel = ones((len(classLabel),),dtype=int)-array(classLabel);
row,col = shape(dataIn);
y0x = y1x = mat(zeros(col));
for i in range(m):
y0x += mat(dataIn[i])*notLabel[i];
y1x += mat(dataIn[i])*classLabel[i];
mean_0 = y0x/(m-sum_1);
mean_1 = y1x/sum_1;
correlation = 0;
for i in range(m):
correlation += (mat(dataIn[i]-mean_0)).T*(mat(dataIn[i]-mean_0))*notLabel[i] \
+(mat(dataIn[i]-mean_1)).T*(mat(dataIn[i]-mean_1))*classLabel[i];
correlation = correlation/m;
return q,mean_0,mean_1,correlation;
def calculate_pxy0(x,n=2):
return ((2*math.pi)**(-n/2))*(linalg.det(correlation)**(-0.5))*exp(-0.5*(x-mean_0).T*correlation.I*(x-mean_0));
def calculate_pxy1(n=2):
return ((2*math.pi)**(-n/2))*(linalg.det(correlation)**(-0.5))*exp(-0.5*(x-mean_1).T*correlation.I*(x-mean_1));
def GDAClass(testPoint,dataIn,classLabel):
import math;
x = testPoint;
q,mean_0,mean_1,correlation = GDA(dataIn,classLabel);
n=shape(dataIn)[0];
py0 = 1-q;
py1 = q;
pxy0 = calculate_pxy0(x,n);
pxy1 = calculate_pxy1(x,n);
if pxy0*py0 pxy1*py1:
return 0;
return 1;
二、Logistic模型的python代码:
点击(此处)折叠或打开
def sigmoid(w,x):
return 1/(1+exp(-w*x))
def logisticRegression(xMat,yMat,maxCycles = 500):
'''
ones((m,n)): 产生m维的向量,且每个值为n
'''
col = shape(xMat)[1];
weight = ones((col,1));
alpha = 0.001;
for j in range(maxCycles):
h = sigmoid(weight,xMat);
err = (yMat-h);
weight += alpha*xMat.transpose*err;
return weight;