费歇尔分类器对图像进行多分类
模式识别小白的第一篇文章
作为一名遥感系的学生相信模式识别的课设会绞尽大家的脑汁,而这课设题目之一就是利用费歇尔分类器对图像进行多分类,让一个小白本白迷惑不已,那么接下来就会为后面的小白解决这个课设大山。
先验数据的采集
费歇尔分类器是一个监督分类器,它的训练是需要先验数据的,之前在网上找过很多资料,它们给出的费歇尔分类器都是非监督分类的,直接把图像所有的像元扔进去让分类器自己分,刚开始我tm竟然还信了,后面才知道当初是多么的单纯,废话不多说,那么如何采集先验数据呢。相信一幅图像大家都能明白:
现在大家能明白吧,就是把图像上苹果和背景的rgb值取出来,采集的这些rgb值将会作为先验数据进行费歇尔分类器的训练了
费歇尔分类器的原理
其实要理解费歇尔分类器还是蛮简单的,但如果要理解背后的原理还是需要自己的推导,相信大家大家学费歇尔分类器的时候都会看到这么一张图:
那么在这里就不细讲原理,在其它平台也很容易搜到,我要讲的就是如何编程实现它,解决大家的课设难题:
算法流程:
1.通过对图像进行采样X1=(R1i,G1i,B1i,Label1i)X2=(R2i,G2i,B2i,
Label2i),其中Label作为对采样数据的一个标识可以为0,1,2…(只要能够区分就可以):
比如:Label=0表示背景,Label=1表示苹果
2.对每个类别分别计算协方差矩阵和平均向量:
-----平均向量(u1,u2)
-------样本类内离散度矩阵Si和总样本类内离散度矩阵Sw
3.计算最佳投影向量w*:
即:W*=(Sw的逆)*(u1-u2)
4.将图像中每个像元的RGB三个值装入一个list中,每次取出一个像元的RGB三维向量Sample,代入训练好的Fisher模型中:
求出两类训练样本的列均值 u_1=(R_1,G_1,B_1),u_2=(R_2,G_2,B_2),将上面求出的W分别乘以训练样本的列均值得到转置之后的两类中心,center_1=dot(WT,u_1),center_2=dot(WT,u_2),对取出的Sample做上述类似处理得到转置后在投影直线上的位置position=dot(WT,Sample)
将position分别与center_1,center_2做减法,得到distance_1和distance_2,Sample离哪个类的distance近就划分到该类中。
好了,费歇尔分类器算法的基本原理就是这样,二分类问题就是我们上述的算法,那么多分类问题如何扩展呢?
大家可以这样考虑一下:比如一张照片有苹果,香蕉和纯白的背景,我们如何用费歇尔进行分类呢?
这就是一个三分类的问题,我们可以理解成两个二分类的问题,苹果和香蕉划分成水果类,先用水果类的先验数据与背景先验数据做一次二分类,然后香蕉和苹果再做一次二分类,那么是不是就完成分类问题了呢。
好了,大家肯会问先验数据咋采集啊,当然是有方法的,大家可以在ps或者其它图像处理软件中使用取像素值,然后自己记录下来就可以了咯。当然本博主不会这么笨的了,自己写个程序就可以了咯!
费歇尔三分类的部分代码如下:
class Fisher:
def __init__(self):
self.Background = []
self.Object_one = []
self.Object_two = []
self.Object_three = []
self.test_one = []
self.w_w = []
def cal_cov_and_avg(self, samples):
# 给定一个类别的数据,计算协方差矩阵和平均向量
u1 = np.mean(samples, axis=0)
cov_m = np.zeros((1, 1))
for s in samples:
t = s - u1
t = t.reshape(1, 3)
cov_m += np.dot(t, t.reshape(3, 1))
return cov_m, u1
第一次在CSDN上写文章,如需本文章完整的代码,可以在评论区留下你的邮箱,我发给你!