日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

Gabor滤波器的特征提取C++实现

發布時間:2025/3/21 c/c++ 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Gabor滤波器的特征提取C++实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

自己項目中用到了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 };/* *@函數名: conv2 *@功能: 卷積運算 *@參數: const Mat &img 原圖片 const Mat ikernel 卷積核convtype type 卷積類型*@返回值: Mat 矩陣卷積后的結果 *@作者: WiseClown *@日期: 2016-1-7*--------------------------------------- *時間 修改人 修改者 *---------------------------------------**/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; }/* *@函數名: MakeGaborKernal *@功能: 生成所有Gabor核 *@參數: *@返回值: void *@作者: WiseClown *@日期: 2016-1-7*--------------------------------------- *時間 修改人 修改者 *---------------------------------------**/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]);}} }/* *@函數名: MakeGaborKernal *@功能: 生成固定方向與固定尺度的Gabor核 *@參數: int ke_h 核函數的高度 int ke_w 核函數的寬度int u Gabor的尺度 int v Gabor的方向Mat &GaborReal Gabor的實部Mat &GaborImg Gabor的虛部*@返回值: Mat 返回的Gabor特征 *@作者: WiseClown *@日期: 2016-1-7*--------------------------------------- *時間 修改人 修改者 *---------------------------------------**/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;}} }/* *@函數名: Gabor_T_Fast1 *@功能: 獲取固定核函數的Gabor特征 *@參數: Mat &src 原圖---彩色圖片int ds_h 下采樣的高度int ds_w 下采樣的寬度Mat kel_GR[Gabor_num] 固定核函數的實部Mat kel_GI[Gabor_num] 固定核函數的虛部*@返回值: Mat 返回的Gabor特征 *@作者: WiseClown *@日期: 2016-1-7*--------------------------------------- *時間 修改人 修改者 *---------------------------------------**/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; }/* *@函數名: Gabor_T_Fast2 *@功能: 獲取固定核函數的Gabor均值與方差二維特征 *@參數: Mat &src 原圖---彩色圖片int ds_h 下采樣的高度int ds_w 下采樣的寬度Mat kel_GR[Gabor_num] 固定核函數的實部Mat kel_GI[Gabor_num] 固定核函數的虛部double* feature 特征值*@返回值: Mat 返回的Gabor特征 *@作者: WiseClown *@日期: 2016-1-7*--------------------------------------- *時間 修改人 修改者 *---------------------------------------**/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;//使用雙線性插值法,使feat_mode_part寬高調整到(ds_w,ds_h)resize(feat_mode_part,tmp2,Size(ds_w,ds_h));tmp3=tmp2.reshape(1,1);//求均值mean和方差stdfloat 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; }/* *@函數名: Create_GaborF *@功能: 獲取Gabor特征 *@參數: Mat &src 原圖---彩色圖片 *@返回值: Mat 返回的Gabor特征 *@作者: WiseClown *@日期: 2016-1-7@說明: *--------------------------------------- *時間 修改人 修改者 *---------------------------------------**/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; }/* *@函數名: getGaborMeanAndVarianceFeature *@功能: 獲取Gabor的均值與方差二維特征 *@參數: Mat &src 原圖---彩色圖片double* feature 特征 *@返回值: 0 特征獲取成功-1 特征獲取失敗 *@作者: WiseClown *@日期: 2016-1-7@說明: *--------------------------------------- *時間 修改人 修改者 *---------------------------------------**/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++实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。