自己項目中用到了Gabor濾波器,于是自己借助Opencv圖像庫,實現了Gabor濾波器的特征提取,用類的形式將其封裝,希望對大家有用>0<。
Gabor參數主要是5個尺度,8個方向,共40個卷積核。本人圖片大小為36*48大小。下采樣為10*11,故特征維數為:10*11*5*40=4400維。針對特征維數過大,可以采用PCA或LDA降維,這里就不展現了。
Gabor.h
#ifndef _GABOR_H
#define _GABOR_H#include <opencv2/opencv.hpp>
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>using namespace cv;
using namespace std;
#define Gabor_num 40
#define U 8
#define V 5class Gabor
{
public:
Gabor():
m_kmax(CV_PI/2),
m_f(
sqrt(2.0)),
m_sigma(CV_PI),
ds_w(10),
ds_h(11),
ke_w(31),
ke_h(31),
raT(0.9){};
void MakeAllGaborKernal();
void MakeGaborKernal(
int ke_h,
int ke_w,
int u,
int v,Mat &GaborReal,Mat &GaborImg);Mat Gabor_T_Fast1(Mat &src,
int ds_h,
int ds_w,Mat kel_GR[Gabor_num],Mat kel_GI[Gabor_num]);
int Gabor_T_Fast2(Mat &src,
int ds_h,
int ds_w,Mat kel_GR[Gabor_num],Mat kel_GI[Gabor_num],
double* feature);Mat Create_GaborF(Mat& src);
int getGaborMeanAndVarianceFeature(Mat &src,
double* feature);
private:
double m_kmax;
double m_f;
double m_sigma;
int ds_w;
int ds_h;
int ke_w;
int ke_h;
double raT;Mat GaborReal[Gabor_num];Mat GaborImg[Gabor_num];};
#endif
Gabor.cpp
#include "Gabor.h"enum convtype
{ full, same,valid
};Mat conv2(
const Mat &img,
const Mat ikernel, convtype type)
{Mat dest;Mat kernel;flip(ikernel,kernel,-
1);Mat source = img;
if(type == full) {source = Mat();
int additionalRows = kernel.rows-
1, additionalCols = kernel.cols-
1;copyMakeBorder(img, source, (additionalRows+
1)/
2, additionalRows/
2, (additionalCols+
1)/
2, additionalCols/
2, BORDER_CONSTANT, Scalar(
0));}Point anchor(kernel.cols - kernel.cols/
2 -
1, kernel.rows - kernel.rows/
2 -
1);
int borderMode = BORDER_CONSTANT;filter2D(source, dest, img.depth(), kernel, anchor,
0, borderMode);
if(type == valid) {dest = dest.colRange((kernel.cols-
1)/
2, dest.cols - kernel.cols/
2).rowRange((kernel.rows-
1)/
2, dest.rows - kernel.rows/
2);}
return dest;
}
void Gabor::MakeAllGaborKernal()
{
int n=
0;
for(
int v=
0;v<V;v++){
for(
int u=
0;u<U;u++){MakeGaborKernal(ke_w,ke_h,u,v,GaborReal[v*
8+u],GaborImg[v*
8+u]);}}
}
void Gabor::MakeGaborKernal(
int ke_h,
int ke_w,
int u,
int v,Mat &GaborReal,Mat &GaborImg)
{
int HarfH=ke_h/
2;
int HarfW=ke_w/
2;
double Qu=CV_PI*u/
8;
double sqsigma=m_sigma*m_sigma;
double Kv=m_kmax/(
pow(m_f,v));
double postmean=
exp(-sqsigma/
2);GaborReal.create(HarfH+HarfW+
1,HarfH+HarfW+
1,CV_32FC1);GaborImg.create(HarfH+HarfW+
1,HarfH+HarfW+
1,CV_32FC1);
float *ptr_real=NULL;
float *ptr_img=NULL;
for(
int j=-HarfH;j<=HarfH;j++){ptr_real=GaborReal.ptr<
float>(j+HarfH);ptr_img=GaborImg.ptr<
float>(j+HarfH);
for(
int i=-HarfW;i<=HarfW;i++){
double tmp1=
exp(-(Kv*Kv*(j*j+i*i)/(
2*sqsigma)));
double tmp2=
cos(Kv*
cos(Qu)*i+Kv*
sin(Qu)*j)-postmean;
double tmp3=
sin(Kv*
cos(Qu)*i+Kv*
sin(Qu)*j);ptr_real[i+HarfW]=Kv*Kv*tmp1*tmp2/sqsigma;ptr_img[i+HarfW]=Kv*Kv*tmp1*tmp3/sqsigma;}}
}Mat Gabor::Gabor_T_Fast1(Mat &src,
int ds_h,
int ds_w,Mat kel_GR[Gabor_num],Mat kel_GI[Gabor_num])
{Mat feature;Mat feature1;
for(
int i=
0;i<Gabor_num;i++){Mat feat_real_part;Mat feat_img_part;Mat feat_mode_part;feat_real_part=conv2(src,kel_GR[i],same);feat_img_part=conv2(src,kel_GI[i],same);multiply(feat_real_part,feat_real_part,feat_real_part);multiply(feat_img_part,feat_img_part,feat_img_part);add(feat_real_part,feat_img_part,feat_mode_part);
sqrt(feat_mode_part,feat_mode_part);Mat tmp2;Mat tmp3;resize(feat_mode_part,tmp2,Size(ds_w,ds_h));tmp3=tmp2.reshape(
1,
1);
float mean=
0;
float std=
0;
float sum1=
0;
float sum2=
0;
for(
int j=
0;j<tmp3.cols;j++){sum1+=tmp3.at<
float>(
0,j);}mean=sum1/(tmp3.cols);
for(
int j=
0;j<tmp3.cols;j++){sum2+=
pow((tmp3.at<
float>(
0,j)-mean),
2);}sum2/=tmp3.cols;
std=
sqrt(sum2);subtract(tmp3,mean,tmp3);divide(tmp3,
std,tmp3);feature.push_back(tmp3);}feature1=feature.reshape(
1,
1);
return feature1;
}
int Gabor::Gabor_T_Fast2(Mat &src,
int ds_h,
int ds_w,Mat kel_GR[Gabor_num],Mat kel_GI[Gabor_num],
double* feature)
{
vector<float> featureTmp;
for(
int i=
0;i<Gabor_num;i++){Mat feat_real_part;Mat feat_img_part;Mat feat_mode_part;feat_real_part=conv2(src,kel_GR[i],same);feat_img_part=conv2(src,kel_GI[i],same);multiply(feat_real_part,feat_real_part,feat_real_part);multiply(feat_img_part,feat_img_part,feat_img_part);add(feat_real_part,feat_img_part,feat_mode_part);
sqrt(feat_mode_part,feat_mode_part);Mat tmp2;Mat tmp3;resize(feat_mode_part,tmp2,Size(ds_w,ds_h));tmp3=tmp2.reshape(
1,
1);
float mean=
0;
float std=
0;
float sum1=
0;
float sum2=
0;
for(
int j=
0;j<tmp3.cols;j++){sum1+=tmp3.at<
float>(
0,j);}mean=sum1/(tmp3.cols);
for(
int j=
0;j<tmp3.cols;j++){sum2+=
pow((tmp3.at<
float>(
0,j)-mean),
2);}sum2/=tmp3.cols;
std=
sqrt(sum2);featureTmp.push_back(mean);featureTmp.push_back(
std);}
for(size_t i=
0; i<featureTmp.size(); ++i){*(feature+i) = featureTmp.at(i);}
return 0;
}Mat Gabor::Create_GaborF(Mat &src)
{MakeAllGaborKernal();Mat feature;
double tmp1=ke_w/
2;
double tmp2=ke_h/
2;
int radius_w =(
int)
floor(tmp1);
int radius_h =(
int)
floor(tmp2);
int center_w = radius_w+
1;
int center_h = radius_h+
1;
int step=
5;Mat kel_GR[Gabor_num],kel_GI[Gabor_num];
int t1=center_h-radius_h+step;
int t2=center_h+radius_h-step;
int t3=center_w-radius_w+step;
int t4=center_w+radius_w-step;
for(
int m=
0;m<Gabor_num;m++){kel_GR[m]=GaborReal[m](Range(t1-
1,t2),Range(t3-
1,t4));kel_GI[m]=GaborImg[m](Range(t1-
1,t2),Range(t3-
1,t4));}feature=Gabor_T_Fast1(src,ds_h,ds_w,kel_GR,kel_GI);
return feature;
}
int Gabor::getGaborMeanAndVarianceFeature(Mat &src,
double* feature)
{MakeAllGaborKernal();
double tmp1=ke_w/
2;
double tmp2=ke_h/
2;
int radius_w =(
int)
floor(tmp1);
int radius_h =(
int)
floor(tmp2);
int center_w = radius_w+
1;
int center_h = radius_h+
1;
int step=
5;Mat kel_GR[Gabor_num],kel_GI[Gabor_num];
int t1=center_h-radius_h+step;
int t2=center_h+radius_h-step;
int t3=center_w-radius_w+step;
int t4=center_w+radius_w-step;
for(
int m=
0;m<Gabor_num;m++){kel_GR[m]=GaborReal[m](Range(t1-
1,t2),Range(t3-
1,t4));kel_GI[m]=GaborImg[m](Range(t1-
1,t2),Range(t3-
1,t4));}Gabor_T_Fast2(src,ds_h,ds_w,kel_GR,kel_GI,feature);
return 0;
}
總結
以上是生活随笔為你收集整理的Gabor滤波器的特征提取C++实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。