CVPR读书笔记[6]:Gabor特征提取
朱金华jinhua1982@gmail.com 2014.08.16 周六
本文是Gabor特征提取三部分之三:
[1]CVPR读书笔记[4]:Gabor特征提取之Gabor核
http://blog.youkuaiyun.com/njzhujinhua/article/details/38460861
[2] CVPR读书笔记[5]:Gabor特征提取之Gabor核的实现
http://blog.youkuaiyun.com/njzhujinhua/article/details/38610281
[3] CVPR读书笔记[6]:Gabor特征提取
http://blog.youkuaiyun.com/njzhujinhua/article/details/38614697
上两节讲到了Gabor滤波器核的原理及实现, 有了滤波器的kernel, 使用该滤波器也就是很简单的事了.
对于图像滤波,一种可以直接在空域进行原图像与kernel进行卷积运算, 另一种是将原图像与kernel分别进行傅里叶变换在频域进行滤波,然后再反变换回来,即用频域滤波代替卷积加快计算速度.
[1]空域滤波
这个直接用filter2D完成了, 首先依次用每个核对原图像进行滤波得到用该Gabor核采集的特征, 并将之变为一行.
最后将所有核采集的特征矩阵变为1行(对32*32的图像,起一个核采集后是1*1024数据, 40个核采集后是40*1024,最后reshape变为1*40960).(这个原本为一列的,大部分理论中讲的也都是按样本特征为列向量来的,后来见svm中样本为行向量,便如此设定了. 设为行向量也方便一个样本的特征的内存拷贝)
Mat FaceFeature_gabor::GetFeature(Mat &src)
{
Mat feature;
Mat feat_part[GABOR_SCALE_NUM][GABOR_ANGLE_NUM];
for (int i=0; i< GABOR_SCALE_NUM; i++)
{
for (int j=0;j<GABOR_ANGLE_NUM;j++)
{
filter2D(src, feat_part[i][j], CV_32F, m_gabor.m_gaborReKernel[i][j]);
Mat tmp;
normalize(feat_part[i][j],tmp,0,255,CV_MINMAX,CV_32FC1);
//test
//imshow("gaborface", tmp);
//waitKey();
//test end
tmp = tmp.reshape(1,1);
feature.push_back(tmp);
}
}
return feature.reshape(1,1);
}
[2]频域滤波
通过将每个Gabor核进行傅里叶变换,得到其频域的滤波核.一个运行的系统,Gabor核设定好后一般不变,于是其频域的滤波核也不会变,这里只需做一次即可.后面对每个人脸采集特征时都是直接使用了.
在变换生成滤波核的大小时需要先将原空域核copyMakeBorder成与要处理的预设的标准人脸大小相匹配, 以便后面在频域要进行的滤波(mulSpetrums运算).
bool FaceFeature_gabor::InitFreqKernel()
{
Mat mergecomplexkernel;
int freqksize=getOptimalDFTSize(m_faceSz.height);
for (int scaleIdx=0;scaleIdx < GABOR_SCALE_NUM; scaleIdx++)
{
for (int angleIdx = 0;angleIdx < GABOR_ANGLE_NUM; angleIdx++)
{
Mat re,im;
copyMakeBorder(m_gabor.m_gaborReKernel[scaleIdx][angleIdx], re,
0,freqksize-m_gabor.m_gaborReKernel[scaleIdx][angleIdx].rows,
0, freqksize-m_gabor.m_gaborReKernel[scaleIdx][angleIdx].cols,
BORDER_CONSTANT, Scalar::all(0));
copyMakeBorder(m_gabor.m_gaborImgKernel[scaleIdx][angleIdx], im,
0,freqksize-m_gabor.m_gaborImgKernel[scaleIdx][angleIdx].rows,
0, freqksize-m_gabor.m_gaborImgKernel[scaleIdx][angleIdx].cols,
BORDER_CONSTANT, Scalar::all(0));
Mat planes[]={re, im};
merge(planes, 2, mergecomplexkernel);
dft(mergecomplexkernel,m_gaborFreqKernel[scaleIdx][angleIdx], DFT_COMPLEX_OUTPUT);
}
}
return true;
}
对于FERET的一个原80*80像素FERET-001\01.tif的人脸处理前后如下由此频域核即可实施对标准化后的脸进行在频域滤波了(先dft,再mulSpectrums,代码略)
前:100*100
得到的GaborFace如下,
其中每行表示8个方向, 每列2个一组,一共5组表示5个尺度. 每组里面的2个上面是使用频域滤波的结果,下面是简单filter2D的结果