opencv里关于HOG特征的提取是通过函数HOGDescriptor()来完成的,主要有下面4个构造函数:
CV_WRAP HOGDescriptor() : winSize(64,128), blockSize(16,16), blockStride(8,8),
cellSize(8,8), nbins(9), derivAperture(1), winSigma(-1),
histogramNormType(HOGDescriptor::L2Hys), L2HysThreshold(0.2), gammaCorrection(true),
nlevels(HOGDescriptor::DEFAULT_NLEVELS)
{}
CV_WRAP HOGDescriptor(Size _winSize, Size _blockSize, Size _blockStride,
Size _cellSize, int _nbins, int _derivAperture=1, double _winSigma=-1,
int _histogramNormType=HOGDescriptor::L2Hys,
double _L2HysThreshold=0.2, bool _gammaCorrection=false,
int _nlevels=HOGDescriptor::DEFAULT_NLEVELS)
: winSize(_winSize), blockSize(_blockSize), blockStride(_blockStride), cellSize(_cellSize),
nbins(_nbins), derivAperture(_derivAperture), winSigma(_winSigma),
histogramNormType(_histogramNormType), L2HysThreshold(_L2HysThreshold),
gammaCorrection(_gammaCorrection), nlevels(_nlevels)
{}
CV_WRAP HOGDescriptor(const String& filename)
{
load(filename);
}
HOGDescriptor(const HOGDescriptor& d)
{
d.copyTo(*this);
}
size_t HOGDescriptor::getDescriptorSize() const
{
CV_Assert(blockSize.width % cellSize.width == 0 &&
blockSize.height % cellSize.height == 0);
CV_Assert((winSize.width - blockSize.width) % blockStride.width == 0 &&
(winSize.height - blockSize.height) % blockStride.height == 0 );
return (size_t)nbins*
(blockSize.width/cellSize.width)*
(blockSize.height/cellSize.height)*
((winSize.width - blockSize.width)/blockStride.width + 1)*
((winSize.height - blockSize.height)/blockStride.height + 1);
}
#include "cv.h"
#include "highgui.h"
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
int main()
{
int ImgWidht = 64;
int ImgHeight = 64;
vector img_path;
vector img_catg;
int nLine = 0;
string buf;
ifstream svm_data( "tran.txt" );
unsigned long n;
while( svm_data )
{
if( getline( svm_data, buf ) )
{
//三种类别,前10个,中间10个,最后10个
if( nLine <10 )
{
img_catg.push_back(0);//图像类别
img_path.push_back( buf );//图像路径
}
else if(nLine <20 )
{
img_catg.push_back(1);
img_path.push_back( buf );//图像路径
}
else
{
img_catg.push_back(2);
img_path.push_back( buf );//图像路径
}
nLine ++;
}
}
svm_data.close();//关闭文件
Mat data_mat, res_mat;
int nImgNum = nLine; //读入样本数量
//样本矩阵,nImgNum:行数代表样本的数量,每一行就是由一张图片计算得到HOG的特征向量,
data_mat = Mat::zeros( nImgNum, 1764, CV_32FC1 ); //HOG特征的位数: 9*(16/8)*(16/8)*[(64-16)/8+1]*[(64-16)/8+1]=1764
//类型矩阵,存储每个样本的类型标志
res_mat = Mat::zeros( nImgNum, 1, CV_32FC1 );
Mat src;
Mat trainImg = Mat::zeros(ImgHeight, ImgWidht, CV_8UC3);//需要分析的图片
for( string::size_type i = 0; i != img_path.size(); i++ )
{
src = imread(img_path[i].c_str(), 1);
cout<<" processing "<descriptors;//结果数组
hog->compute(trainImg, descriptors, Size(1,1), Size(0,0)); //调用计算函数开始计算
if (i==0)
{
data_mat = Mat::zeros( nImgNum, descriptors.size(), CV_32FC1 ); //根据输入图片大小进行分配空间
}
cout<<"HOG dims: "<::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
{
data_mat.at(i,n) = *iter;
n++;
}
//cout<rows<(i, 0) = img_catg[i];
cout<<" end processing "< img_tst_path;
ifstream img_tst( "test.txt" );
while( img_tst )
{
if( getline( img_tst, buf ) )
{
img_tst_path.push_back( buf );
}
}
img_tst.close();
Mat test;
char line[512];
ofstream predict_txt( "SVM_PREDICT.txt" );
for( string::size_type j = 0; j != img_tst_path.size(); j++ )
{
test = imread( img_tst_path[j].c_str(), 1);//读入图像
resize(test, trainImg, cv::Size(ImgWidht,ImgHeight), 0, 0, INTER_CUBIC);//要搞成同样的大小才可以检测到
HOGDescriptor *hog=new HOGDescriptor(cvSize(ImgWidht,ImgHeight),cvSize(16,16),cvSize(8,8),cvSize(8,8),9); //窗口大小,块大小,块滑动增量,cell的大小,bins的个数
vectordescriptors;//结果数组
hog->compute(trainImg, descriptors,Size(1,1), Size(0,0)); //调用计算函数开始计算
cout<<"The Detection Result:"<::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
{
SVMtrainMat.at(0,n) = *iter;
n++;
}
int ret = svm.predict(SVMtrainMat);
std::sprintf( line, "%s %d\r\n", img_tst_path[j].c_str(), ret );
printf("%s %d\r\n", img_tst_path[j].c_str(), ret);//输出预测的结果,ret的值就代表类别
//getchar();
predict_txt<