最近要做图像特征提取,可能要用下HOG特征,所以研究了下OpenCV的HOG描述子。OpenCV中的HOG特征提取功能使用了HOGDescriptor这个类来进行封装,其中也有现成的行人检测的接口。然而,无论是OpenCV官方说明文档还是各个中英文网站目前都没有这个类的使用说明,所以在这里把研究的部分心得分享一下。
- objdetect/include/opencv2/objdetect.hpp
- 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), free_coef(-1.f)
- nlevels(HOGDescriptor::DEFAULT_NLEVELS),signedGradient(false)
- {}
winSize : 窗口的大小
blockSize :块的大小
cellSize: 胞元的大小
nbins: 方向bin的个数 nBins表示在一个胞元(cell)中统计梯度的方向数目,例如nBins=9时,在一个胞元内统计9个方向的梯度直方图,每个方向为360/9=40度。
- 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) bool _signedGradient=false)
- : winSize(_winSize), blockSize(_blockSize), blockStride(_blockStride), cellSize(_cellSize),
- nbins(_nbins), derivAperture(_derivAperture), winSigma(_winSigma),
- histogramNormType(_histogramNormType), L2HysThreshold(_L2HysThreshold),
- gammaCorrection(_gammaCorrection), free_coef(-1.f),nlevels(_nlevels),signedGradient(_signedGradient)
- {}
-
- CV_WRAP HOGDescriptor(const String& filename)
- {
- load(filename);
- }
- HOGDescriptor(const HOGDescriptor& d)
- {
- d.copyTo(*this);
- }
- 我们看到HOGDescriptor一共有4个构造函数,前三个有CV_WRAP前缀,表示它们是从DLL里导出的函数,即我们在程序当中可以调用的函数;最后一个没有上述的前缀,所以我们暂时用不到,它其实就是一个拷贝构造函数。
-
- CV_WRAP size_t getDescriptorSize() const;
- CV_WRAP bool checkDetectorSize() const;
- CV_WRAP double getWinSigma() const;
- CV_WRAP virtual void setSVMDetector(InputArray _svmdetector);
- virtual bool read(FileNode& fn);
- virtual void write(FileStorage& fs, const String& objname) const;
- CV_WRAP virtual bool load(const String& filename, const String& objname=String());
- CV_WRAP virtual void save(const String& filename, const String& objname=String()) const;
- virtual void copyTo(HOGDescriptor& c) const;
- CV_WRAP virtual void compute(const Mat& img,
- CV_OUT vector<float>& descriptors,
- Size winStride=Size(), Size padding=Size(),
- const vector<Point>& locations=vector<Point>()) const;
- //with found weights output
- CV_WRAP virtual void detect(const Mat& img, CV_OUT vector<Point>& foundLocations,
- CV_OUT vector<double>& weights,
- double hitThreshold=0, Size winStride=Size(),
- Size padding=Size(),
- const vector<Point>& searchLocations=vector<Point>()) const;
- //without found weights output
- virtual void detect(const Mat& img, CV_OUT vector<Point>& foundLocations,
- double hitThreshold=0, Size winStride=Size(),
- Size padding=Size(),
- const vector<Point>& searchLocations=vector<Point>()) const;
- //with result weights output
- CV_WRAP virtual void detectMultiScale(const Mat& img, CV_OUT vector<Rect>& foundLocations,
- CV_OUT vector<double>& foundWeights, double hitThreshold=0,
- Size winStride=Size(), Size padding=Size(), double scale=1.05,
- double finalThreshold=2.0,bool useMeanshiftGrouping = false) const;
- //without found weights output
- virtual void detectMultiScale(const Mat& img, CV_OUT vector<Rect>& foundLocations,
- double hitThreshold=0, Size winStride=Size(),
- Size padding=Size(), double scale=1.05,
- double finalThreshold=2.0, bool useMeanshiftGrouping = false) const;
- CV_WRAP virtual void computeGradient(const Mat& img, CV_OUT Mat& grad, CV_OUT Mat& angleOfs,
- Size paddingTL=Size(), Size paddingBR=Size()) const;
- CV_WRAP static vector<float> getDefaultPeopleDetector();
- CV_WRAP static vector<float> getDaimlerPeopleDetector();
- CV_PROP Size winSize;
- CV_PROP Size blockSize;
- CV_PROP Size blockStride;
- CV_PROP Size cellSize;
- CV_PROP int nbins;
- CV_PROP int derivAperture;
- CV_PROP double winSigma;
- CV_PROP int histogramNormType;
- CV_PROP double L2HysThreshold;
- CV_PROP bool gammaCorrection;
- CV_PROP vector<float> svmDetector;
- CV_PROP int nlevels;
- CV_PROP bool signedGradient;
- UMat colSvmDector;
- float free_coef ;
-
- // evaluate specified ROI and return confidence value for each location
- void detectROI(const cv::Mat& img, const vector<cv::Point> &locations,
- CV_OUT std::vector<cv::Point>& foundLocations, CV_OUT std::vector<double>& confidences,
- double hitThreshold = 0, cv::Size winStride = Size(),
- cv::Size padding = Size()) const;
- // evaluate specified ROI and return confidence value for each location in multiple scales
- void detectMultiScaleROI(const cv::Mat& img,
- CV_OUT std::vector<cv::Rect>& foundLocations,
- std::vector<DetectionROI>& locations,
- double hitThreshold = 0,
- int groupThreshold = 0) const;
- // read/parse Dalal's alt model file
- void readALTModel(std::string modelfile);
- };
- void groupRectangles(std::vector<cv::Rect>& rectList,std::vactor<double> & weight, int groupThreshold,double eps) const;
- }
-
HOG描述子维度
在确定了上述的参数后,我们就可以计算出一个HOG描述子的维度了。OpenCV中的HOG源代码是按照下面的式子计算出描述子的维度的。
- 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);
- }
=++++++++++++++++++++++提取 HOG 特征+++++++++++++++++++++++++=
参考:
OpenCV HOGDescriptor 参数图解
opencv中的 HOGDescriptor 类
Opencv得到HOG特征(HOGDescriptor 的使用)
目标检测学习_1(用opencv自带hog实现行人检测)