【OpenCV流程+代码分析】Opencv HOG行人检测 源码分析

【原文:http://blog.csdn.net/ttransposition/article/details/11874285】

OpenCV demo演示见本人的另一篇灌水博客 http://blog.csdn.net/soidnhp/article/details/11720801

本人源码分析见 http://blog.csdn.net/soidnhp/article/details/11880425

参考文献:《N. Dalal and B. Triggs, “Histograms of Oriented Gradients for Human Detection,”Proc. IEEE Conf. Computer Vision and Pattern Recognition,2005.》

参考链接 http://www.cnblogs.com/tornadomeet/archive/2012/08/15/2640754.html

一、基本思想

     上图是目标检测的基本流程。

     HOG属于特征提取,它统计梯度直方图特征。具体来说就是将梯度方向(0->360°)划分为9个区间,将图像化为16x16的若干个block,每个block在化为4个cell(8x8)。对每一个cell,算出每一点的梯度方向和模,按梯度方向增加对应bin的值,最终综合N个cell的梯度直方图形成一个高维描述子向量。实际实现的时候会有各种插值。

     选用的分类器是经典的SVM。

    检测框架为经典的滑动窗口法,即在位置空间和尺度空间遍历搜索检测。

二、基本概念

      原始图像打完补丁后就直接用固定的窗口在图像中移动,计算检测窗口下的梯度,形成描述子向量,然后就直接SVM了

三、HOG算法流程

算法流程比较简单:

1、gamma校正

       r=0.5,暗区对比度提高,亮区对比度下降

2、计算梯度

      微分算子[-1 0 1],取RGB通道中模值最大的为该像素点的梯度。

      插值策略:对与该点梯度方向相邻的两个bin按距离进行线性插值。

3 、权值

   高斯权值:与到block中心负相关,对于图中的大圆圈

   cell中心权值:到对称cell中心的“距离”正相关,对应下图中小方块到十字的距离。

  这一部分比较复杂,  每一个像素点还要对cell插值。

1)F,J,G,K区域内的像素点对四个cell都有贡献,比如P4对cell 0 的权重是倒对称cell中心即cell 3的“距离” P4-cell 3 即图中绿色虚线的“长度”,对其它cell 的权值依次类推

2)B,C,E,I,N,O,H,L区域的像素点要对两个cell中心插值。比如P2虽然处在cell 1中,但是对cell 0 也有贡献,对虚线中的红,绿两个十字所在的cell 也有贡献。那对cell 0的权重计算方法同P4。

取到对称cell 中心的 “距离”,即到绿色中心的“距离”。

3)A,D,M,P,区域的点对周围的四个cell也有贡献,但是block覆盖的只有一个cell,自然只要对其本身所在的cell插值即可。比如P1,到对称cell 中心的“距离”,即图中的cell中心。

但是要注意:cell的编号顺序是从上到下,从左到右,即(cell 0 cell 1 cell 2 cell 3)但是四个cell的偏移量存储顺序却是(cell 0 ->cell 2 ->cell 1->cell 3)

  

 

 

4、归一化

L2 Hys归一化,比较简单

5、获取整个检测窗口内的所有block的梯度直方图组成一个很高很高维的描述子向量

用查表替代了八重循环,大大减少了时间开销。

最笨的方法是依次循环:

1.检测窗口在输入图像中滑动

2.block在检测窗口win中滑动

3.cell在block中滑动

4.在cell中循环获取像素的梯度值

每一层循环都是2维的这样下来就是八重循环…………子子孙孙无穷尽也

作者通过预先计算好的pixData,blockData基本上化为了3重循环。

1.循环图像中的每一个检测窗口win

2.循环检测窗口内的每一个block

3.循环每一个block中的像素点,getblock()

每一层都是一维。

6、SVM分类

     计算到分类超平面的距离

四、HOG算法OpenCV实现流程

五、源码分析

http://blog.csdn.net/soidnhp/article/details/11880425


前一篇博客大体讲了下思路,对比较难理解的关系有些图示 http://blog.csdn.net/soidnhp/article/details/11874285  

[cpp]  view plain copy
  1. /*M/////////////////////////////////////////////////////////////////////////////////////// 
  2. // 
  3. //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 
  4. // 
  5. //  By downloading, copying, installing or using the software you agree to this license. 
  6. //  If you do not agree to this license, do not download, install, 
  7. //  copy or use the software. 
  8. // 
  9. // 
  10. //                           License Agreement 
  11. //                For Open Source Computer Vision Library 
  12. // 
  13. // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. 
  14. // Copyright (C) 2009, Willow Garage Inc., all rights reserved. 
  15. // Third party copyrights are property of their respective owners. 
  16. // 
  17. // Redistribution and use in source and binary forms, with or without modification, 
  18. // are permitted provided that the following conditions are met: 
  19. // 
  20. //   * Redistribution's of source code must retain the above copyright notice, 
  21. //     this list of conditions and the following disclaimer. 
  22. // 
  23. //   * Redistribution's in binary form must reproduce the above copyright notice, 
  24. //     this list of conditions and the following disclaimer in the documentation 
  25. //     and/or other materials provided with the distribution. 
  26. // 
  27. //   * The name of the copyright holders may not be used to endorse or promote products 
  28. //     derived from this software without specific prior written permission. 
  29. // 
  30. // This software is provided by the copyright holders and contributors "as is" and 
  31. // any express or implied warranties, including, but not limited to, the implied 
  32. // warranties of merchantability and fitness for a particular purpose are disclaimed. 
  33. // In no event shall the Intel Corporation or contributors be liable for any direct, 
  34. // indirect, incidental, special, exemplary, or consequential damages 
  35. // (including, but not limited to, procurement of substitute goods or services; 
  36. // loss of use, data, or profits; or business interruption) however caused 
  37. // and on any theory of liability, whether in contract, strict liability, 
  38. // or tort (including negligence or otherwise) arising in any way out of 
  39. // the use of this software, even if advised of the possibility of such damage. 
  40. // 
  41. //M*/  
  42. #include   
  43. #include "precomp.hpp"  //包含了 objdetect.hpp   
  44. #include   
  45. #ifdef HAVE_IPP  
  46. #include "ipp.h"  
  47. #endif  
  48. /****************************************************************************************\ 
  49.       The code below is implementation of HOG (Histogram-of-Oriented Gradients) 
  50.       descriptor and object detection, introduced by Navneet Dalal and Bill Triggs. 
  51.  
  52.       The computed feature vectors are compatible with the 
  53.       INRIA Object Detection and Localization Toolkit 
  54.       (http://pascal.inrialpes.fr/soft/olt/) 
  55. \****************************************************************************************/  
  56.   
  57. namespace cv  
  58. {  
  59.   
  60. size_t HOGDescriptor::getDescriptorSize() const  
  61. {  
  62.     CV_Assert(blockSize.width % cellSize.width == 0 &&  
  63.         blockSize.height % cellSize.height == 0);  
  64.     CV_Assert((winSize.width - blockSize.width) % blockStride.width == 0 &&  
  65.         (winSize.height - blockSize.height) % blockStride.height == 0 );  
  66.     return (size_t)nbins*  
  67.         (blockSize.width/cellSize.width)*  
  68.         (blockSize.height/cellSize.height)*  
  69.         ((winSize.width - blockSize.width)/blockStride.width + 1)*  
  70.         ((winSize.height - blockSize.height)/blockStride.height + 1);//描述向量总长度  
  71. }  
  72.   
  73. double HOGDescriptor::getWinSigma() const  
  74. {  
  75.     return winSigma >= 0 ? winSigma : (blockSize.width + blockSize.height)/8.; //默认-1  
  76. }  
  77.   
  78. bool HOGDescriptor::checkDetectorSize() const  
  79. {  
  80.     size_t detectorSize = svmDetector.size(), descriptorSize = getDescriptorSize();  
  81.     return detectorSize == 0 ||  
  82.         detectorSize == descriptorSize ||  
  83.         detectorSize == descriptorSize + 1;  
  84. }  
  85.   
  86. void HOGDescriptor::setSVMDetector(InputArray _svmDetector)  
  87. {  
  88.     _svmDetector.getMat().convertTo(svmDetector, CV_32F);  
  89.     CV_Assert( checkDetectorSize() );  
  90. }  
  91.   
  92. #define CV_TYPE_NAME_HOG_DESCRIPTOR "opencv-object-detector-hog"  
  93.   
  94. bool HOGDescriptor::read(FileNode& obj)  
  95. {  
  96.     if( !obj.isMap() )  
  97.         return false;  
  98.     FileNodeIterator it = obj["winSize"].begin();  
  99.     it >> winSize.width >> winSize.height;  
  100.     it = obj["blockSize"].begin();  
  101.     it >> blockSize.width >> blockSize.height;  
  102.     it = obj["blockStride"].begin();  
  103.     it >> blockStride.width >> blockStride.height;  
  104.     it = obj["cellSize"].begin();  
  105.     it >> cellSize.width >> cellSize.height;  
  106.     obj["nbins"] >> nbins;  
  107.     obj["derivAperture"] >> derivAperture;  
  108.     obj["winSigma"] >> winSigma;  
  109.     obj["histogramNormType"] >> histogramNormType;  
  110.     obj["L2HysThreshold"] >> L2HysThreshold;  
  111.     obj["gammaCorrection"] >> gammaCorrection;  
  112.     obj["nlevels"] >> nlevels;  
  113.   
  114.     FileNode vecNode = obj["SVMDetector"];  
  115.     if( vecNode.isSeq() )  
  116.     {  
  117.         vecNode >> svmDetector;  
  118.         CV_Assert(checkDetectorSize());  
  119.     }  
  120.     return true;  
  121. }  
  122.   
  123. void HOGDescriptor::write(FileStorage& fs, const String& objName) const  
  124. {  
  125.     if( !objName.empty() )  
  126.         fs << objName;  
  127.   
  128.     fs << "{" CV_TYPE_NAME_HOG_DESCRIPTOR  
  129.     << "winSize" << winSize  
  130.     << "blockSize" << blockSize  
  131.     << "blockStride" << blockStride  
  132.     << "cellSize" << cellSize  
  133.     << "nbins" << nbins  
  134.     << "derivAperture" << derivAperture  
  135.     << "winSigma" << getWinSigma()  
  136.     << "histogramNormType" << histogramNormType  
  137.     << "L2HysThreshold" << L2HysThreshold  
  138.     << "gammaCorrection" << gammaCorrection  
  139.     << "nlevels" << nlevels;  
  140.     if( !svmDetector.empty() )  
  141.         fs << "SVMDetector" << svmDetector;  
  142.     fs << "}";  
  143. }  
  144.   
  145. bool HOGDescriptor::load(const String& filename, const String& objname)  
  146. {  
  147.     FileStorage fs(filename, FileStorage::READ);  
  148.     FileNode obj = !objname.empty() ? fs[objname] : fs.getFirstTopLevelNode();  
  149.     return read(obj);  
  150. }  
  151.   
  152. void HOGDescriptor::save(const String& filename, const String& objName) const  
  153. {  
  154.     FileStorage fs(filename, FileStorage::WRITE);  
  155.     write(fs, !objName.empty() ? objName : FileStorage::getDefaultObjectName(filename));  
  156. }  
  157.   
  158. void HOGDescriptor::copyTo(HOGDescriptor& c) const  
  159. {  
  160.     c.winSize = winSize;  
  161.     c.blockSize = blockSize;  
  162.     c.blockStride = blockStride;  
  163.     c.cellSize = cellSize;  
  164.     c.nbins = nbins;  
  165.     c.derivAperture = derivAperture;  
  166.     c.winSigma = winSigma;  
  167.     c.histogramNormType = histogramNormType;  
  168.     c.L2HysThreshold = L2HysThreshold;  
  169.     c.gammaCorrection = gammaCorrection;  
  170.     c.svmDetector = svmDetector;  
  171.     c.nlevels = nlevels;  
  172. }  
  173. //返回 grad:梯度的模在与梯度方向相邻的两个bin的插值值,qangle:与梯度方向相邻的两个bin的编号  
  174. void HOGDescriptor::computeGradient(const Mat& img, Mat& grad, Mat& qangle,  
  175.                                     Size paddingTL, Size paddingBR) const  
  176. {  
  177.     CV_Assert( img.type() == CV_8U || img.type() == CV_8UC3 );  
  178.   
  179.     Size gradsize(img.cols + paddingTL.width + paddingBR.width,  
  180.                   img.rows + paddingTL.height + paddingBR.height);  
  181.     grad.create(gradsize, CV_32FC2);  // ,与该点梯度方向相邻两个bin的梯度模值,由该点线性插值得到  
  182.     qangle.create(gradsize, CV_8UC2); // [0..nbins-1] - quantized gradient orientation,与该点梯度方向相邻两个bin的编号  
  183.     Size wholeSize;  
  184.     Point roiofs;  
  185.     img.locateROI(wholeSize, roiofs);   //img如果是一个大图像IMG的Region of interesting,那么IMG和img共享内存  
  186.                                         //比如IMG(120x120),img取自IMG的一部分TL坐标(10,10),BR坐标(109,109)那么尺寸为(100x100)  
  187.                                         //这个函数就返回父矩阵IMG的size(120x120),以及img在IMG中的坐标偏移(roiofs.x=10,roiofs.y=10)  
  188.     /* 
  189.     Locates the matrix header within a parent matrix. 
  190.     wholeSize – Output parameter that contains the size of the whole matrix containing *this as a part 
  191.     ofs – Output parameter that contains an offset of *this inside the whole matrix. 
  192.     */  
  193.     int i, x, y;  
  194.     int cn = img.channels();  
  195.   
  196.     Mat_<float> _lut(1, 256); //gamma 校正Look up table,Mat_ 简化版的 Mat,元素访问直接 用(x,y),无需 .at,但是速度是一样的  
  197.     const float* lut = &_lut(0,0);  //只能读  
  198.   
  199.     if( gammaCorrection )  
  200.         for( i = 0; i < 256; i++ )  
  201.             _lut(0,i) = std::sqrt((float)i);    //gammma 校正 r=0.5,暗区对比度提高,亮区对比度下降  
  202.     else  
  203.         for( i = 0; i < 256; i++ )  
  204.             _lut(0,i) = (float)i;  
  205.   
  206.     AutoBuffer<int> mapbuf(gradsize.width + gradsize.height + 4); //自动buffer,就不需要我们malloc,free  
  207.     int* xmap = (int*)mapbuf + 1;  
  208.     int* ymap = xmap + gradsize.width + 2;  
  209.   
  210.     const int borderType = (int)BORDER_REFLECT_101;  
  211.     //一种很奇怪的插值方式,扩展出来的边缘用原图像中的像素值,并没有真正扩展存储空间  
  212.     //比如说原图为 100x100,现在要访问(-10,-10)的值,但是内存里面不不存在这个值,这种插值方法就是在原图像中找个像素点(比如(5,6))的值作为(-10,-10)的值  
  213.     //也就是将扩展后的坐标范围比如(120x120)映射到(100x100)。x,y坐标分别映射,映射表存在xmap,ymap。上面的例子中xmap[-10]=5,ymap[-10]=6  
  214.     for( x = -1; x < gradsize.width + 1; x++ )  
  215.         xmap[x] = borderInterpolate(x - paddingTL.width + roiofs.x,wholeSize.width, borderType) - roiofs.x;  
  216.     for( y = -1; y < gradsize.height + 1; y++ )  
  217.         ymap[y] = borderInterpolate(y - paddingTL.height + roiofs.y,wholeSize.height, borderType) - roiofs.y;  
  218.   
  219.     // x- & y- derivatives for the whole row  
  220.     int width = gradsize.width;  
  221.     AutoBuffer<float> _dbuf(width*4);  
  222.     float* dbuf = _dbuf;  
  223.     Mat Dx(1, width, CV_32F, dbuf);  
  224.     Mat Dy(1, width, CV_32F, dbuf + width);  
  225.     Mat Mag(1, width, CV_32F, dbuf + width*2);  
  226.     Mat Angle(1, width, CV_32F, dbuf + width*3);  
  227.   
  228.     int _nbins = nbins;  
  229.     float angleScale = (float)(_nbins/CV_PI);   //算某一弧度,对应落在哪一个bin的scale  
  230. #ifdef HAVE_IPP //intel的ipp库,优化  
  231.     Mat lutimg(img.rows,img.cols,CV_MAKETYPE(CV_32F,cn));   //cn ,为1/3,对于类型 CV_32FC1、CV_32FC3  
  232.     Mat hidxs(1, width, CV_32F);  
  233.     Ipp32f* pHidxs  = (Ipp32f*)hidxs.data;  
  234.     Ipp32f* pAngles = (Ipp32f*)Angle.data;  
  235.   
  236.     IppiSize roiSize;  
  237.     roiSize.width = img.cols;  
  238.     roiSize.height = img.rows;  
  239.   
  240.     //对原始图像,进行gamma校正,结果保存在 imglutPtr  
  241.     for( y = 0; y < roiSize.height; y++ )  
  242.     {  
  243.        const uchar* imgPtr = img.data + y*img.step;  
  244.        float* imglutPtr = (float*)(lutimg.data + y*lutimg.step);  
  245.   
  246.        for( x = 0; x < roiSize.width*cn; x++ )  
  247.        {  
  248.           imglutPtr[x] = lut[imgPtr[x]];    //查表 gamma校正  
  249.        }  
  250.     }  
  251.   
  252. #endif  
  253.     //好长的循环体,计算了四个梯度的四个量 Dx,Dy, Angle,Mag,最终是保存了Angle,Mag两个量给后续的工作用  
  254.     for( y = 0; y < gradsize.height; y++ )  
  255.     {  
  256.         //行指针(加上了补丁)  
  257. #ifdef HAVE_IPP  
  258.         const float* imgPtr  = (float*)(lutimg.data + lutimg.step*ymap[y]);  
  259.         const float* prevPtr = (float*)(lutimg.data + lutimg.step*ymap[y-1]);  
  260.         const float* nextPtr = (float*)(lutimg.data + lutimg.step*ymap[y+1]);  
  261. #else  
  262.         const uchar* imgPtr  = img.data + img.step*ymap[y];  
  263.         const uchar* prevPtr = img.data + img.step*ymap[y-1];  
  264.         const uchar* nextPtr = img.data + img.step*ymap[y+1];  
  265. #endif  
  266.         float* gradPtr = (float*)grad.ptr(y);   //Returns a pointer to the specified matrix row.  
  267.         uchar* qanglePtr = (uchar*)qangle.ptr(y);  
  268.           
  269.         //计算 水平和垂直梯度 保存在 dbuf 的前两段  
  270.         if( cn == 1 )  
  271.         {  
  272.             for( x = 0; x < width; x++ )  
  273.             {  
  274.                 int x1 = xmap[x];  
  275. #ifdef HAVE_IPP  
  276.                 dbuf[x] = (float)(imgPtr[xmap[x+1]] - imgPtr[xmap[x-1]]);   //水平微分模板 [-1 0 1]  
  277.                 dbuf[width + x] = (float)(nextPtr[x1] - prevPtr[x1]);       //垂直微分模板 [-1 0 1]'  
  278. #else  
  279.                 dbuf[x] = (float)(lut[imgPtr[xmap[x+1]]] - lut[imgPtr[xmap[x-1]]]);     //dbuf length: width*4  
  280.                 dbuf[width + x] = (float)(lut[nextPtr[x1]] - lut[prevPtr[x1]]);     //使用了IPP优化,就已经gamm校正了,这里是先gamm校正然后在计算梯度  
  281. #endif  
  282.             }  
  283.         }  
  284.         else    ////取B,G,R通道中梯度模最大的梯度作为该点的梯度,  
  285.         {  
  286.             for( x = 0; x < width; x++ )  
  287.             {  
  288.                 int x1 = xmap[x]*3; //height*width*element,element:8UC3/32FC3  
  289.                 float dx0, dy0, dx, dy, mag0, mag;  
  290. #ifdef HAVE_IPP  
  291.                 const float* p2 = imgPtr + xmap[x+1]*3;   
  292.                 const float* p0 = imgPtr + xmap[x-1]*3;   
  293.                 //R通道的梯度  
  294.                 dx0 = p2[2] - p0[2];  
  295.                 dy0 = nextPtr[x1+2] - prevPtr[x1+2];      
  296.                 mag0 = dx0*dx0 + dy0*dy0;  
  297.                 //G通道的梯度  
  298.                 dx = p2[1] - p0[1];  
  299.                 dy = nextPtr[x1+1] - prevPtr[x1+1];  
  300.                 mag = dx*dx + dy*dy;  
  301.           
  302.                 if( mag0 < mag ) //取G,R通道中梯度模最大的  
  303.                 {  
  304.                     dx0 = dx;  
  305.                     dy0 = dy;  
  306.                     mag0 = mag;  
  307.                 }  
  308.                 //B通道的梯度  
  309.                 dx = p2[0] - p0[0];  
  310.                 dy = nextPtr[x1] - prevPtr[x1];  
  311.                 mag = dx*dx + dy*dy;  
  312. #else  
  313.                 const uchar* p2 = imgPtr + xmap[x+1]*3;  
  314.                 const uchar* p0 = imgPtr + xmap[x-1]*3;  
  315.   
  316.                 dx0 = lut[p2[2]] - lut[p0[2]];  
  317.                 dy0 = lut[nextPtr[x1+2]] - lut[prevPtr[x1+2]];  
  318.                 mag0 = dx0*dx0 + dy0*dy0;  
  319.   
  320.                 dx = lut[p2[1]] - lut[p0[1]];  
  321.                 dy = lut[nextPtr[x1+1]] - lut[prevPtr[x1+1]];  
  322.                 mag = dx*dx + dy*dy;  
  323.   
  324.                 if( mag0 < mag )  
  325.                 {  
  326.                     dx0 = dx;  
  327.                     dy0 = dy;  
  328.                     mag0 = mag;  
  329.                 }  
  330.   
  331.                 dx = lut[p2[0]] - lut[p0[0]];  
  332.                 dy = lut[nextPtr[x1]] - lut[prevPtr[x1]];  
  333.                 mag = dx*dx + dy*dy;  
  334.  #endif  
  335.                 if( mag0 < mag ) //取B,G,R通道中梯度模最大的  
  336.                 {  
  337.                     dx0 = dx;  
  338.                     dy0 = dy;  
  339.                     mag0 = mag;  
  340.                 }  
  341.   
  342.                 dbuf[x] = dx0;  
  343.                 dbuf[x+width] = dy0;  
  344.             }  
  345.         }  
  346. #ifdef HAVE_IPP  
  347.         ippsCartToPolar_32f((const Ipp32f*)Dx.data, (const Ipp32f*)Dy.data, (Ipp32f*)Mag.data, pAngles, width);  
  348.         for( x = 0; x < width; x++ )  
  349.         {  
  350.            if(pAngles[x] < 0.f)  
  351.              pAngles[x] += (Ipp32f)(CV_PI*2.);  
  352.         }  
  353.   
  354.         ippsNormalize_32f(pAngles, pAngles, width, 0.5f/angleScale, 1.f/angleScale);  
  355.         ippsFloor_32f(pAngles,(Ipp32f*)hidxs.data,width);  
  356.         ippsSub_32f_I((Ipp32f*)hidxs.data,pAngles,width);  
  357.         ippsMul_32f_I((Ipp32f*)Mag.data,pAngles,width);  
  358.   
  359.         ippsSub_32f_I(pAngles,(Ipp32f*)Mag.data,width);  
  360.         ippsRealToCplx_32f((Ipp32f*)Mag.data,pAngles,(Ipp32fc*)gradPtr,width);  
  361. #else  
  362.         //计算梯度的模和角度,默认结果为弧度  
  363.         cartToPolar( Dx, Dy, Mag, Angle, false );   //Calculates the magnitude and angle of 2D vectors. angle(I) = atan2(y(I); x(I))  
  364. #endif  
  365.         for( x = 0; x < width; x++ )  
  366.         {  
  367. #ifdef HAVE_IPP  
  368.             int hidx = (int)pHidxs[x];  
  369. #else  
  370.             //保存该梯度方向在左右相邻的bin的模,本来只有一个模何来的两个?插值!  
  371.             //线性插值,比如某点算出来应该属于 bin 7.6,但是我们的bin都是整数的,四舍五入,把他划分到bin 8又太粗糙了  
  372.             //那就按该点到bin7,bin8的距离分配,这样部分属于8,部分属于7。  
  373.             float mag = dbuf[x+width*2], angle = dbuf[x+width*3]*angleScale - 0.5f; // 每一格 pi/9, 那现在算 t落在哪一格自然是 t/(pi/9)  
  374.             int hidx = cvFloor(angle);  //向下取整  
  375.             angle -= hidx;  
  376.             gradPtr[x*2] = mag*(1.f - angle);   //binx的大小是梯度方向和模的共同体现  
  377.             gradPtr[x*2+1] = mag*angle;  
  378. #endif  
  379.             if( hidx < 0 )  
  380.                 hidx += _nbins;  
  381.             else if( hidx >= _nbins )  
  382.                 hidx -= _nbins;  
  383.             assert( (unsigned)hidx < (unsigned)_nbins );  
  384.               
  385.             //保存与该梯度方向相邻的左右两个bin编号  
  386.             qanglePtr[x*2] = (uchar)hidx;   //也是向下取整  
  387.             hidx++;  
  388.             hidx &= hidx < _nbins ? -1 : 0;  // hidx &= ( (hidx < _nbins ) ? -1 : 0;),如果hidx < nbins good;如果超过了,就算子bin 0 ;-1的补码是全1  
  389.             qanglePtr[x*2+1] = (uchar)hidx;  
  390.         }  
  391.     }  
  392. }  
  393.   
  394.   
  395. struct HOGCache  
  396. {  
  397.     struct BlockData  
  398.     {  
  399.         BlockData() : histOfs(0), imgOffset() {}  
  400.         int histOfs;  
  401.         Point imgOffset;  
  402.     };  
  403.   
  404.     struct PixData  
  405.     {  
  406.         size_t gradOfs, qangleOfs;  
  407.         int histOfs[4];  
  408.         float histWeights[4];  
  409.         float gradWeight;  
  410.     };  
  411.   
  412.     HOGCache();  
  413.     HOGCache(const HOGDescriptor* descriptor,  
  414.         const Mat& img, Size paddingTL, Size paddingBR,  
  415.         bool useCache, Size cacheStride);  
  416.     virtual ~HOGCache() {};  
  417.     virtual void init(const HOGDescriptor* descriptor,  
  418.         const Mat& img, Size paddingTL, Size paddingBR,  
  419.         bool useCache, Size cacheStride);  
  420.   
  421.     Size windowsInImage(Size imageSize, Size winStride) const;  
  422.     Rect getWindow(Size imageSize, Size winStride, int idx) const;  
  423.   
  424.     const float* getBlock(Point pt, float* buf);  
  425.     virtual void normalizeBlockHistogram(float* histogram) const;  
  426.   
  427.     vector pixData;  
  428.     vector blockData;  
  429.   
  430.     bool useCache;  
  431.     vector<int> ymaxCached;  
  432.     Size winSize, cacheStride;  
  433.     Size nblocks, ncells;  
  434.     int blockHistogramSize;  
  435.     int count1, count2, count4;  
  436.     Point imgoffset;  
  437.     Mat_<float> blockCache;  
  438.     Mat_ blockCacheFlags;  
  439.   
  440.     Mat grad, qangle;  
  441.     const HOGDescriptor* descriptor;  
  442. };  
  443.   
  444.   
  445. HOGCache::HOGCache()  
  446. {  
  447.     useCache = false;  
  448.     blockHistogramSize = count1 = count2 = count4 = 0;  
  449.     descriptor = 0;  
  450. }  
  451.   
  452. HOGCache::HOGCache(const HOGDescriptor* _descriptor,  
  453.         const Mat& _img, Size _paddingTL, Size _paddingBR,  
  454.         bool _useCache, Size _cacheStride)  
  455. {  
  456.     init(_descriptor, _img, _paddingTL, _paddingBR, _useCache, _cacheStride);  
  457. }  
  458.   
  459. void HOGCache::init(const HOGDescriptor* _descriptor,  
  460.         const Mat& _img, Size _paddingTL, Size _paddingBR,  
  461.         bool _useCache, Size _cacheStride)  
  462. {  
  463.     descriptor = _descriptor;  
  464.     cacheStride = _cacheStride;  
  465.     useCache = _useCache;  
  466.     /*--------------------------------------计算梯度----------------------------------------------*/  
  467.     //返回值  
  468.     //size:img.cols + paddingTL.width + paddingBR.width,img.rows + paddingTL.height + paddingBR.height,类型 CV_32FC2  
  469.     //grad:梯度的模在与梯度方向相邻的两个bin的插值值  
  470.     //qangle:与梯度方向相邻的两个bin的编号  
  471.     descriptor->computeGradient(_img, grad, qangle, _paddingTL, _paddingBR);  
  472.     imgoffset = _paddingTL;  
  473.   
  474.     winSize = descriptor->winSize;   //默认值:winSize(64,128)  
  475.     Size blockSize = descriptor->blockSize;//blockSize(16,16)  
  476.     Size blockStride = descriptor->blockStride;//lockStride(8,8)  
  477.     Size cellSize = descriptor->cellSize;//cellSize(8,8)  
  478.     int i, j, nbins = descriptor->nbins;//nbins(9)  
  479.     int rawBlockSize = blockSize.width*blockSize.height;  
  480.   
  481.     nblocks = Size((winSize.width - blockSize.width)/blockStride.width + 1,  
  482.                    (winSize.height - blockSize.height)/blockStride.height + 1);  
  483.            //这种算法非常直观,也许你会觉得可以和下面一样直接除,但是当(winSize.height - blockSize.height) % blockStride.height 不为0时,就不一定  
  484.            //比如 blockSize=4,blockStride=3,winSize.width =9,那么直接除9/3=3,但是只能有两个block, 4|3|2,只能移动一次  
  485.     ncells = Size(blockSize.width/cellSize.width, blockSize.height/cellSize.height);  
  486.     blockHistogramSize = ncells.width*ncells.height*nbins;//默认2*2*9  
  487.   
  488.     if( useCache )  //  
  489.     {  
  490.         Size cacheSize((grad.cols - blockSize.width)/cacheStride.width+1,  
  491.                        (winSize.height/cacheStride.height)+1);  
  492.         blockCache.create(cacheSize.height, cacheSize.width*blockHistogramSize);  
  493.         blockCacheFlags.create(cacheSize);  
  494.         size_t cacheRows = blockCache.rows;  
  495.         ymaxCached.resize(cacheRows);  
  496.         for(size_t ii = 0; ii < cacheRows; ii++ )  
  497.             ymaxCached[ii] = -1;  
  498.     }  
  499.   
  500.     Mat_<float> weights(blockSize);//16*16 高斯模板  
  501.     float sigma = (float)descriptor->getWinSigma();//-1  
  502.     float scale = 1.f/(sigma*sigma*2);  
  503.   
  504.     for(i = 0; i < blockSize.height; i++)  
  505.         for(j = 0; j < blockSize.width; j++)  
  506.         {  
  507.             float di = i - blockSize.height*0.5f;  
  508.             float dj = j - blockSize.width*0.5f;//中心  
  509.             weights(i,j) = std::exp(-(di*di + dj*dj)*scale);//weights(i,j)=exp(-(distance/sigma)^2)  
  510.         }  
  511.   
  512.     blockData.resize(nblocks.width*nblocks.height);  
  513.     pixData.resize(rawBlockSize*3);// vector::resize(newsize,value),不是Mat::resize,16*16*3个结构体  
  514.     /*  
  515.     vector pixData; 
  516.     struct PixData{ 
  517.         size_t gradOfs, qangleOfs; 
  518.         int histOfs[4]; 
  519.         float histWeights[4]; 
  520.         float gradWeight; 
  521.     }; 
  522.     */  
  523.     // Initialize 2 lookup tables, pixData & blockData.  
  524.     // Here is why:  
  525.     //  
  526.     // The detection algorithm runs in 4 nested loops (at each pyramid layer):  
  527.     //  loop over the windows within the input image  
  528.     //    loop over the blocks within each window  
  529.     //      loop over the cells within each block  
  530.     //        loop over the pixels in each cell  
  531.     //  
  532.     // As each of the loops runs over a 2-dimensional array,  
  533.     // we could get 8(!) nested loops in total, which is very-very slow.  
  534.     //  
  535.     // To speed the things up, we do the following:  
  536.     //   1. loop over windows is unrolled in the HOGDescriptor::{compute|detect} methods;  
  537.     //         inside we compute the current search window using getWindow() method.  
  538.     //         Yes, it involves some overhead (function call + couple of divisions),  
  539.     //         but it's tiny in fact.  
  540.     //   2. loop over the blocks is also unrolled. Inside we use pre-computed blockData[j]  
  541.     //         to set up gradient and histogram pointers.  
  542.     //   3. loops over cells and pixels in each cell are merged  
  543.     //       (since there is no overlap between cells, each pixel in the block is processed once)  
  544.     //      and also unrolled. Inside we use PixData[k] to access the gradient values and  
  545.     //      update the histogram  
  546.     //  
  547.     count1 = count2 = count4 = 0;  
  548.     for( j = 0; j < blockSize.width; j++ )//16,先水平,再垂直  
  549.         for( i = 0; i < blockSize.height; i++ )//16  
  550.         {  
  551.             PixData* data = 0;  
  552.             float cellX = (j+0.5f)/cellSize.width - 0.5f;   //这是干什么 ???  
  553.             float cellY = (i+0.5f)/cellSize.height - 0.5f;  
  554.             int icellX0 = cvFloor(cellX);   //-1(j=0..3),0(j=4..11),1(j=12..15)  
  555.             int icellY0 = cvFloor(cellY);     
  556.             int icellX1 = icellX0 + 1, icellY1 = icellY0 + 1;//0 1 2   
  557.             cellX -= icellX0;  
  558.             cellY -= icellY0;  
  559.               
  560.             if( (unsigned)icellX0 < (unsigned)ncells.width &&    // icellX0 == 0  
  561.                 (unsigned)icellX1 < (unsigned)ncells.width ) //判断条件时特别小心,int 转成了 unsigned,(unsigned)(-1)=2^32-1,真对这作者无语  
  562.             {  
  563.                 //  icellX0 == 0,icellY0 == 0 对相邻的四个cell都有贡献,即F,J,G,K区域  
  564.                 if( (unsigned)icellY0 < (unsigned)ncells.height && // cellX,cellY 范围(0,1)  
  565.                     (unsigned)icellY1 < (unsigned)ncells.height )  
  566.                 {  
  567.                     data = &pixData[rawBlockSize*2 + (count4++)];  
  568.                     data->histOfs[0] = (icellX0*ncells.height + icellY0)*nbins;//cell 0 在整个block的bin中的偏移  
  569.                     data->histWeights[0] = (1.f - cellX)*(1.f - cellY);  //到对称中心的“距离”即cell 3  
  570.                     data->histOfs[1] = (icellX1*ncells.height + icellY0)*nbins;//cell 1的偏移 2*9  
  571.                     data->histWeights[1] = cellX*(1.f - cellY);         //到对称中心的“距离”即 cell 2  
  572.                     data->histOfs[2] = (icellX0*ncells.height + icellY1)*nbins;//cell 2的偏移 1*9  
  573.                     data->histWeights[2] = (1.f - cellX)*cellY;         //到对称中心的“距离”即 cell 1  
  574.                     data->histOfs[3] = (icellX1*ncells.height + icellY1)*nbins;//cell 3的偏移3*9  
  575.                     data->histWeights[3] = cellX*cellY;                 //到对称中心的“距离”即 cell 0  
  576.                 }  
  577.                 else    // icellX0 == 0,icellY0 == -1/1,对左右相邻的两个cell有贡献,即B,C,N,O  
  578.                 {  
  579.                     // cellX 范围(0,1),cellY 范围 (0.5,1)/(0,0.5)  
  580.                     data = &pixData[rawBlockSize + (count2++)];  
  581.                     //下部分的cellY范围也落在(0.5,1),icellY1==icellY0 == 1  
  582.                     if( (unsigned)icellY0 < (unsigned)ncells.height )//icellY0 == 1  
  583.                     {  
  584.                         icellY1 = icellY0;  
  585.                         cellY = 1.f - cellY;  
  586.                     }  
  587.                     data->histOfs[0] = (icellX0*ncells.height + icellY1)*nbins;// 上部分0;下部分1  
  588.                     data->histWeights[0] = (1.f - cellX)*cellY;  
  589.                     data->histOfs[1] = (icellX1*ncells.height + icellY1)*nbins;// 上部分2;下部分3  
  590.                     data->histWeights[1] = cellX*cellY;  
  591.                     data->histOfs[2] = data->histOfs[3] = 0;// 均为0  
  592.                     data->histWeights[2] = data->histWeights[3] = 0;  
  593.                 }  
  594.             }  
  595.             else //icellX0 == -1/1,cellX范围(0.5,1)/(0,0.5)  
  596.             {  
  597.                 //右部分的cellX范围也落在(0.5,1),icellX1==icellX0 == 1  
  598.                 if( (unsigned)icellX0 < (unsigned)ncells.width )  
  599.                 {  
  600.                     icellX1 = icellX0;  
  601.                     cellX = 1.f - cellX;  
  602.                 }  
  603.                 //E,H,I,L  
  604.                 if( (unsigned)icellY0 < (unsigned)ncells.height &&  
  605.                     (unsigned)icellY1 < (unsigned)ncells.height )  
  606.                 {  
  607.                     data = &pixData[rawBlockSize + (count2++)];  
  608.                     data->histOfs[0] = (icellX1*ncells.height + icellY0)*nbins;//左:0,右:2*9  
  609.                     data->histWeights[0] = cellX*(1.f - cellY);  
  610.                     data->histOfs[1] = (icellX1*ncells.height + icellY1)*nbins;//左:1*9 右:3*9  
  611.                     data->histWeights[1] = cellX*cellY;  
  612.                     data->histOfs[2] = data->histOfs[3] = 0;  
  613.                     data->histWeights[2] = data->histWeights[3] = 0;  
  614.                 }  
  615.                 // A,D,M,P  
  616.                 else  
  617.                 {  
  618.                     data = &pixData[count1++];  
  619.                     if( (unsigned)icellY0 < (unsigned)ncells.height )  
  620.                     {  
  621.                         icellY1 = icellY0;  
  622.                         cellY = 1.f - cellY;  
  623.                     }  
  624.                     data->histOfs[0] = (icellX1*ncells.height + icellY1)*nbins;  
  625.                     data->histWeights[0] = cellX*cellY;  
  626.                     data->histOfs[1] = data->histOfs[2] = data->histOfs[3] = 0;  
  627.                     data->histWeights[1] = data->histWeights[2] = data->histWeights[3] = 0;  
  628.                 }  
  629.             }  
  630.             data->gradOfs = (grad.cols*i + j)*2; //block窗口的(0,0)位置有相对于整个图像的偏移,此偏移为相对于block(0,0)的偏移  
  631.             data->qangleOfs = (qangle.cols*i + j)*2;//计算方式很古怪,但是你画张图就明白了(grad.cols*i多算的==+j少算的),实际上 block窗口的(0,0)的offset加上此offset就可以直接在grad中找到对应的梯度  
  632.             data->gradWeight = weights(i,j); //该点的高斯权值,大小与到block中心的距离成反比  
  633.         }  
  634.   
  635.     assert( count1 + count2 + count4 == rawBlockSize );//16*16  
  636.     // defragment pixData,整理碎片.  
  637.     //数据合并  xxx.........yyy.........zzz.........->xxxyyyzzz..................  
  638.     //(.表示未赋值空间,x为count1存储的数据,y为count2存储的数据...)  
  639.     for( j = 0; j < count2; j++ )  
  640.         pixData[j + count1] = pixData[j + rawBlockSize];  
  641.     for( j = 0; j < count4; j++ )  
  642.         pixData[j + count1 + count2] = pixData[j + rawBlockSize*2];  
  643.     count2 += count1;  
  644.     count4 += count2;  
  645.   
  646.     // initialize blockData  
  647.     /* 
  648.     struct BlockData{ 
  649.         BlockData() : histOfs(0), imgOffset() {} 
  650.         int histOfs; 
  651.         Point imgOffset; 
  652.     }; 
  653.     */  
  654.     for( j = 0; j < nblocks.width; j++ )  
  655.         for( i = 0; i < nblocks.height; i++ )  
  656.         {  
  657.             BlockData& data = blockData[j*nblocks.height + i];  
  658.             data.histOfs = (j*nblocks.height + i)*blockHistogramSize;  
  659.             data.imgOffset = Point(j*blockStride.width,i*blockStride.height);  
  660.         }  
  661. }  
  662.   
  663.   
  664. const float* HOGCache::getBlock(Point pt, float* buf)  
  665. {  
  666.     float* blockHist = buf;  
  667.     assert(descriptor != 0);  
  668.   
  669.     Size blockSize = descriptor->blockSize;  
  670.     pt += imgoffset; //imgoffset:padingTL,先前减去pading,现在又加过来,为嘛????  
  671.   
  672.     CV_Assert( (unsigned)pt.x <= (unsigned)(grad.cols - blockSize.width) &&  
  673.                (unsigned)pt.y <= (unsigned)(grad.rows - blockSize.height) );  
  674.   
  675.     if( useCache ) //默认未使用  
  676.     {  
  677.         CV_Assert( pt.x % cacheStride.width == 0 &&  
  678.                    pt.y % cacheStride.height == 0 );  
  679.         Point cacheIdx(pt.x/cacheStride.width,  
  680.                       (pt.y/cacheStride.height) % blockCache.rows);  
  681.         if( pt.y != ymaxCached[cacheIdx.y] )  
  682.         {  
  683.             Mat_ cacheRow = blockCacheFlags.row(cacheIdx.y);  
  684.             cacheRow = (uchar)0;  
  685.             ymaxCached[cacheIdx.y] = pt.y;  
  686.         }  
  687.   
  688.         blockHist = &blockCache[cacheIdx.y][cacheIdx.x*blockHistogramSize];  
  689.         uchar& computedFlag = blockCacheFlags(cacheIdx.y, cacheIdx.x);  
  690.         if( computedFlag != 0 )  
  691.             return blockHist;  
  692.         computedFlag = (uchar)1; // set it at once, before actual computing  
  693.     }  
  694.   
  695.     int k, C1 = count1, C2 = count2, C4 = count4;//64,128,256  
  696.     const float* gradPtr = (const float*)(grad.data + grad.step*pt.y) + pt.x*2;//block(0,0)在与其梯度方向相邻的两个bin上的插值分量  
  697.     const uchar* qanglePtr = qangle.data + qangle.step*pt.y + pt.x*2;//与block(0,0)梯度方向相邻的两个bin的bin编号  
  698.   
  699.     CV_Assert( blockHist != 0 );  
  700. #ifdef HAVE_IPP  
  701.     ippsZero_32f(blockHist,blockHistogramSize);  
  702. #else  
  703.     for( k = 0; k < blockHistogramSize; k++ )  
  704.         blockHist[k] = 0.f;  
  705. #endif  
  706.   
  707.     const PixData* _pixData = &pixData[0];//pixData在init中已经计算好了,相对于block(0,0)的偏移  
  708.     //ADMP  
  709.     for( k = 0; k < C1; k++ )  
  710.     {  
  711.         const PixData& pk = _pixData[k];  
  712.         const float* a = gradPtr + pk.gradOfs;//该点的梯度指针  
  713.         float w = pk.gradWeight*pk.histWeights[0];  
  714.         const uchar* h = qanglePtr + pk.qangleOfs;//该点的梯度编号指针  
  715.         int h0 = h[0], h1 = h[1];//梯度编号  
  716.         float* hist = blockHist + pk.histOfs[0];//该点的hist指针  
  717.         float t0 = hist[h0] + a[0]*w;  
  718.         float t1 = hist[h1] + a[1]*w;  
  719.         hist[h0] = t0; hist[h1] = t1;  
  720.     }  
  721.     //BCEINPHL  
  722.     for( ; k < C2; k++ )  
  723.     {  
  724.         const PixData& pk = _pixData[k];  
  725.         const float* a = gradPtr + pk.gradOfs;  
  726.         float w, t0, t1, a0 = a[0], a1 = a[1];  
  727.         const uchar* h = qanglePtr + pk.qangleOfs;  
  728.         int h0 = h[0], h1 = h[1];  
  729.   
  730.         float* hist = blockHist + pk.histOfs[0];  
  731.         w = pk.gradWeight*pk.histWeights[0];  
  732.         t0 = hist[h0] + a0*w;  
  733.         t1 = hist[h1] + a1*w;  
  734.         hist[h0] = t0; hist[h1] = t1;  
  735.   
  736.         hist = blockHist + pk.histOfs[1];  
  737.         w = pk.gradWeight*pk.histWeights[1];  
  738.         t0 = hist[h0] + a0*w;  
  739.         t1 = hist[h1] + a1*w;  
  740.         hist[h0] = t0; hist[h1] = t1;  
  741.     }  
  742.     //FGJK  
  743.     for( ; k < C4; k++ )  
  744.     {  
  745.         const PixData& pk = _pixData[k];  
  746.         const float* a = gradPtr + pk.gradOfs;  
  747.         float w, t0, t1, a0 = a[0], a1 = a[1];  
  748.         const uchar* h = qanglePtr + pk.qangleOfs;  
  749.         int h0 = h[0], h1 = h[1];  
  750.   
  751.         float* hist = blockHist + pk.histOfs[0];  
  752.         w = pk.gradWeight*pk.histWeights[0];  
  753.         t0 = hist[h0] + a0*w;  
  754.         t1 = hist[h1] + a1*w;  
  755.         hist[h0] = t0; hist[h1] = t1;  
  756.   
  757.         hist = blockHist + pk.histOfs[1];  
  758.         w = pk.gradWeight*pk.histWeights[1];  
  759.         t0 = hist[h0] + a0*w;  
  760.         t1 = hist[h1] + a1*w;  
  761.         hist[h0] = t0; hist[h1] = t1;  
  762.   
  763.         hist = blockHist + pk.histOfs[2];  
  764.         w = pk.gradWeight*pk.histWeights[2];  
  765.         t0 = hist[h0] + a0*w;  
  766.         t1 = hist[h1] + a1*w;  
  767.         hist[h0] = t0; hist[h1] = t1;  
  768.   
  769.         hist = blockHist + pk.histOfs[3];  
  770.         w = pk.gradWeight*pk.histWeights[3];  
  771.         t0 = hist[h0] + a0*w;  
  772.         t1 = hist[h1] + a1*w;  
  773.         hist[h0] = t0; hist[h1] = t1;  
  774.     }  
  775.   
  776.     normalizeBlockHistogram(blockHist);  
  777.   
  778.     return blockHist;  
  779. }  
  780.   
  781. //L2HysThreshold:先L2归一化,再限制所有的值的范围(0,0.2),再重新L2归一化  
  782. void HOGCache::normalizeBlockHistogram(float* _hist) const  
  783. {  
  784.     float* hist = &_hist[0];  
  785. #ifdef HAVE_IPP  
  786.     size_t sz = blockHistogramSize;  
  787. #else  
  788.     size_t i, sz = blockHistogramSize;  
  789. #endif  
  790.   
  791.     float sum = 0;  
  792. #ifdef HAVE_IPP  
  793.     ippsDotProd_32f(hist,hist,sz,&sum);  
  794. #else  
  795.     for( i = 0; i < sz; i++ )  
  796.         sum += hist[i]*hist[i];  
  797. #endif  
  798.   
  799.     float scale = 1.f/(std::sqrt(sum)+sz*0.1f), thresh = (float)descriptor->L2HysThreshold;  
  800. #ifdef HAVE_IPP  
  801.     ippsMulC_32f_I(scale,hist,sz);  
  802.     ippsThreshold_32f_I( hist, sz, thresh, ippCmpGreater );  
  803.     ippsDotProd_32f(hist,hist,sz,&sum);  
  804. #else  
  805.     for( i = 0, sum = 0; i < sz; i++ )  
  806.     {  
  807.         hist[i] = std::min(hist[i]*scale, thresh);  
  808.         sum += hist[i]*hist[i];  
  809.     }  
  810. #endif  
  811.   
  812.     scale = 1.f/(std::sqrt(sum)+1e-3f);  
  813. #ifdef HAVE_IPP  
  814.     ippsMulC_32f_I(scale,hist,sz);  
  815. #else  
  816.     for( i = 0; i < sz; i++ )  
  817.         hist[i] *= scale;  
  818. #endif  
  819. }  
  820.   
  821.   
  822. Size HOGCache::windowsInImage(Size imageSize, Size winStride) const  
  823. {  
  824.     return Size((imageSize.width - winSize.width)/winStride.width + 1,  
  825.                 (imageSize.height - winSize.height)/winStride.height + 1);  
  826. }  
  827.   
  828. Rect HOGCache::getWindow(Size imageSize, Size winStride, int idx) const  
  829. {  
  830.     int nwindowsX = (imageSize.width - winSize.width)/winStride.width + 1;  
  831.     int y = idx / nwindowsX;  
  832.     int x = idx - nwindowsX*y;  
  833.     return Rect( x*winStride.width, y*winStride.height, winSize.width, winSize.height );  
  834. }  
  835.   
  836.   
  837. void HOGDescriptor::compute(const Mat& img, vector<float>& descriptors,  
  838.                             Size winStride, Size padding,  
  839.                             const vector& locations) const  
  840. {  
  841.     if( winStride == Size() )  
  842.         winStride = cellSize;  
  843.     Size cacheStride(gcd(winStride.width, blockStride.width),  
  844.                      gcd(winStride.height, blockStride.height));  
  845.     size_t nwindows = locations.size();  
  846.     padding.width = (int)alignSize(std::max(padding.width, 0), cacheStride.width);  
  847.     padding.height = (int)alignSize(std::max(padding.height, 0), cacheStride.height);  
  848.     Size paddedImgSize(img.cols + padding.width*2, img.rows + padding.height*2);  
  849.   
  850.     HOGCache cache(this, img, padding, padding, nwindows == 0, cacheStride);  
  851.   
  852.     if( !nwindows )  
  853.         nwindows = cache.windowsInImage(paddedImgSize, winStride).area();  
  854.   
  855.     const HOGCache::BlockData* blockData = &cache.blockData[0];  
  856.   
  857.     int nblocks = cache.nblocks.area();  
  858.     int blockHistogramSize = cache.blockHistogramSize;  
  859.     size_t dsize = getDescriptorSize(); //检测窗口内描述子的总长度,即总bin数  
  860.     descriptors.resize(dsize*nwindows);  //整张图片的描述子长度  
  861.   
  862.     forsize_t i = 0; i < nwindows; i++ )  
  863.     {  
  864.         float* descriptor = &descriptors[i*dsize];  
  865.   
  866.         Point pt0;  
  867.         if( !locations.empty() )  
  868.         {  
  869.             pt0 = locations[i];  
  870.             if( pt0.x < -padding.width || pt0.x > img.cols + padding.width - winSize.width ||  
  871.                 pt0.y < -padding.height || pt0.y > img.rows + padding.height - winSize.height )  
  872.                 continue;  
  873.         }  
  874.         else//默认是这种情况  
  875.         {  
  876.             pt0 = cache.getWindow(paddedImgSize, winStride, (int)i).tl() - Point(padding);  
  877.             CV_Assert(pt0.x % cacheStride.width == 0 && pt0.y % cacheStride.height == 0);  
  878.         }  
  879.   
  880.         forint j = 0; j < nblocks; j++ )  
  881.         {  
  882.             const HOGCache::BlockData& bj = blockData[j];  
  883.             Point pt = pt0 + bj.imgOffset;  
  884.   
  885.             float* dst = descriptor + bj.histOfs;  
  886.             const float* src = cache.getBlock(pt, dst);  
  887.             if( src != dst )  
  888. #ifdef HAVE_IPP  
  889.                ippsCopy_32f(src,dst,blockHistogramSize);  
  890. #else  
  891.                 forint k = 0; k < blockHistogramSize; k++ )  
  892.                     dst[k] = src[k];  
  893. #endif  
  894.         }  
  895.     }  
  896. }  
  897.   
  898.   
  899. void HOGDescriptor::detect(const Mat& img,  
  900.     vector& hits, vector<double>& weights, double hitThreshold,  
  901.     Size winStride, Size padding, const vector& locations) const  
  902.     /* 
  903.     img – Source image. CV_8UC1 and CV_8UC4 types are supported for now. 
  904.     found_locations – Left-top corner points of detected objects boundaries. 
  905.     hit_threshold – Threshold for the distance between features and SVM classifying plane. 
  906.     win_stride – Window stride. It must be a multiple of block stride. 
  907.     padding – Mock parameter to keep the CPU interface compatibility. It must be (0,0). 
  908.     */  
  909.     //hog->detect(smallerImg, locations, hitsWeights, hitThreshold, winStride, padding);  
  910.     //smallerImg size:(cvRound(img.cols/scale), cvRound(img.rows/scale));  
  911. {  
  912.     hits.clear();  
  913.     if( svmDetector.empty() )  
  914.         return;  
  915.   
  916.     if( winStride == Size() )//未指定winStride的情况下,winStride==(8,8)  
  917.         winStride = cellSize;  
  918.     Size cacheStride(gcd(winStride.width, blockStride.width),  
  919.                      gcd(winStride.height, blockStride.height));// gcd,求最大公约数,默认结果(8,8)  
  920.     size_t nwindows = locations.size(); // 默认:0  
  921.     //对于我们自己设定的LTpading=BRpading=pading,进行调整使得pading的宽高与casheStride的宽高对齐,类似于4字节补充对齐  
  922.     padding.width = (int)alignSize(std::max(padding.width, 0), cacheStride.width);//alignSize(m, n),返回n的倍数中大于等于m的最小值  
  923.     padding.height = (int)alignSize(std::max(padding.height, 0), cacheStride.height);  
  924.     Size paddedImgSize(img.cols + padding.width*2, img.rows + padding.height*2);  
  925.     /*--------------------------------------------------------------------*/  
  926.     //  1.计算梯度的模,方向  
  927.     //  2.预先计算好了一个block的bin基偏移、高斯权重、插值距离  
  928.     HOGCache cache(this, img, padding, padding, nwindows == 0, cacheStride);    //调用了,computeGradient,计算了pading后的梯度  
  929.                                                                                 //Note:尺度变化时,重新计算了梯度  
  930.                                                                                 //histOfs = (j*nblocks.height + i)*blockHistogramSize;  
  931.                                                                                 //imgOffset = Point(j*blockStride.width,i*blockStride.height);  
  932.   
  933.     if( !nwindows )  
  934.         nwindows = cache.windowsInImage(paddedImgSize, winStride).area();//整个img 的检测窗口数  
  935.   
  936.     const HOGCache::BlockData* blockData = &cache.blockData[0];  
  937.   
  938.     int nblocks = cache.nblocks.area(); //检测窗口内的block数  
  939.     int blockHistogramSize = cache.blockHistogramSize; //一个block的histogram的bin总数,2*2*9  
  940.     size_t dsize = getDescriptorSize();//一个窗口的描述子总数  
  941.   
  942.     double rho = svmDetector.size() > dsize ? svmDetector[dsize] : 0;// > 成立的情况,即svm的 惩罚项系数 C 不为0  
  943.     vector<float> blockHist(blockHistogramSize);  
  944.   
  945.     forsize_t i = 0; i < nwindows; i++ )  
  946.     {  
  947.         Point pt0;  
  948.         if( !locations.empty() )  
  949.         {  
  950.             pt0 = locations[i];  
  951.             if( pt0.x < -padding.width || pt0.x > img.cols + padding.width - winSize.width ||  
  952.                 pt0.y < -padding.height || pt0.y > img.rows + padding.height - winSize.height )  
  953.                 continue;  
  954.         }  
  955.         else  
  956.         {  
  957.             //得到第i个检测窗口在pading之后的图像中的区域,这里减去pading,后面geitblock又pt += imgoffset;  
  958.             pt0 = cache.getWindow(paddedImgSize, winStride, (int)i).tl()- Point(padding);     
  959.             CV_Assert(pt0.x % cacheStride.width == 0 && pt0.y % cacheStride.height == 0);  
  960.         }  
  961.         double s = rho;  
  962.         const float* svmVec = &svmDetector[0];  
  963. #ifdef HAVE_IPP  
  964.         int j;  
  965. #else  
  966.         int j, k;  
  967. #endif  
  968.         for( j = 0; j < nblocks; j++, svmVec += blockHistogramSize )  
  969.         {  
  970.             const HOGCache::BlockData& bj = blockData[j];//检测窗口中第j个block  
  971.             // .histOfs = (j*nblocks.height + i)*blockHistogramSize;  
  972.             // .imgOffset = Point(j*blockStride.width,i*blockStride.height);  
  973.             Point pt = pt0 + bj.imgOffset;  //得到第i个检测窗口中第j个block在pading之后的图像中的TL坐标  
  974.             //得到以pt为TL坐标的block的hist(2*2*9)数据  
  975.             const float* vec = cache.getBlock(pt, &blockHist[0]);  
  976. #ifdef HAVE_IPP  
  977.             Ipp32f partSum;  
  978.             ippsDotProd_32f(vec,svmVec,blockHistogramSize,&partSum);  
  979.             s += (double)partSum;  
  980. #else  
  981.             //计算到分类超平面的距离  
  982.             for( k = 0; k <= blockHistogramSize - 4; k += 4 )  
  983.                 s += vec[k]*svmVec[k] + vec[k+1]*svmVec[k+1] +  
  984.                     vec[k+2]*svmVec[k+2] + vec[k+3]*svmVec[k+3];  
  985.             for( ; k < blockHistogramSize; k++ )  
  986.                 s += vec[k]*svmVec[k];  
  987. #endif  
  988.         }  
  989.         if( s >= hitThreshold )  
  990.         {  
  991.             hits.push_back(pt0);  
  992.             weights.push_back(s);  
  993.         }  
  994.     }  
  995. }  
  996.   
  997. void HOGDescriptor::detect(const Mat& img, vector& hits, double hitThreshold,  
  998.                            Size winStride, Size padding, const vector& locations) const  
  999. {  
  1000.     vector<double> weightsV;  
  1001.     detect(img, hits, weightsV, hitThreshold, winStride, padding, locations);  
  1002. }  
  1003.   
  1004. class HOGInvoker : public ParallelLoopBody  
  1005. {  
  1006. public:  
  1007.     HOGInvoker( const HOGDescriptor* _hog, const Mat& _img,  
  1008.                 double _hitThreshold, Size _winStride, Size _padding,  
  1009.                 const double* _levelScale, std::vector * _vec, Mutex* _mtx,  
  1010.                 std::vector<double>* _weights=0, std::vector<double>* _scales=0 )  
  1011.     {  
  1012.         hog = _hog;  
  1013.         img = _img;  
  1014.         hitThreshold = _hitThreshold;  
  1015.         winStride = _winStride;  
  1016.         padding = _padding;  
  1017.         levelScale = _levelScale;  
  1018.         vec = _vec;  
  1019.         weights = _weights;  
  1020.         scales = _scales;  
  1021.         mtx = _mtx;  
  1022.     }  
  1023.   
  1024.     void operator()( const Range& range ) const  
  1025.     {  
  1026.         int i, i1 = range.start, i2 = range.end;  
  1027.         double minScale = i1 > 0 ? levelScale[i1] : i2 > 1 ? levelScale[i1+1] : std::max(img.cols, img.rows);  
  1028.         Size maxSz(cvCeil(img.cols/minScale), cvCeil(img.rows/minScale));  
  1029.         Mat smallerImgBuf(maxSz, img.type());  
  1030.         vector locations;  
  1031.         vector<double> hitsWeights;  
  1032.   
  1033.         for( i = i1; i < i2; i++ )  
  1034.         {  
  1035.             double scale = levelScale[i];  
  1036.             Size sz(cvRound(img.cols/scale), cvRound(img.rows/scale));//cvRound:四舍五入  
  1037.             Mat smallerImg(sz, img.type(), smallerImgBuf.data);  
  1038.             if( sz == img.size() )  //scale==1,不需要用 smallerImgBuf的空间,所以最大的内存应该是 scale==levelScale[i1+1]的情况  
  1039.                 smallerImg = Mat(sz, img.type(), img.data, img.step);//共享数据  
  1040.             else  
  1041.                 resize(img, smallerImg, sz);//dst的内存空间超过src时,dst的空间是不是并没有缩小呢,  
  1042.                                             //也就是说是不是先释放内存,再按照新的size重新申请,从程序上看一直霸占原始内存空间才能起到减少内存申请释放所耗费的时间  
  1043.             hog->detect(smallerImg, locations, hitsWeights, hitThreshold, winStride, padding);  
  1044.             Size scaledWinSize = Size(cvRound(hog->winSize.width*scale), cvRound(hog->winSize.height*scale));  
  1045.   
  1046.             mtx->lock();  
  1047.             forsize_t j = 0; j < locations.size(); j++ )  
  1048.             {  
  1049.                 vec->push_back(Rect(cvRound(locations[j].x*scale),  
  1050.                                     cvRound(locations[j].y*scale),  
  1051.                                     scaledWinSize.width, scaledWinSize.height));//恢复为原图像中的位置  
  1052.                 if (scales)  
  1053.                 {  
  1054.                     scales->push_back(scale);  
  1055.                 }  
  1056.             }  
  1057.             mtx->unlock();  
  1058.   
  1059.             if (weights && (!hitsWeights.empty()))  
  1060.             {  
  1061.                 mtx->lock();  
  1062.                 for (size_t j = 0; j < locations.size(); j++)  
  1063.                 {  
  1064.                     weights->push_back(hitsWeights[j]);  
  1065.                 }  
  1066.                 mtx->unlock();  
  1067.             }  
  1068.         }  
  1069.     }  
  1070.   
  1071.     const HOGDescriptor* hog;  
  1072.     Mat img;  
  1073.     double hitThreshold;  
  1074.     Size winStride;  
  1075.     Size padding;  
  1076.     const double* levelScale;  
  1077.     std::vector* vec;  
  1078.     std::vector<double>* weights;  
  1079.     std::vector<double>* scales;  
  1080.     Mutex* mtx;  
  1081. };  
  1082.   
  1083.   
  1084. void HOGDescriptor::detectMultiScale(  
  1085.     const Mat& img, vector& foundLocations, vector<double>& foundWeights,  
  1086.     double hitThreshold, Size winStride, Size padding,  
  1087.     double scale0, double finalThreshold, bool useMeanshiftGrouping) const  
  1088.     /* 
  1089.     img – Source image. 
  1090.     foundLocations – Detected objects boundaries. 
  1091.     foundWeights   -   
  1092.     hit_threshold – Threshold for the distance between features and SVM classifying plane,到分类超平面的距离,越大则要求越严格,一般设为0. 
  1093.     win_stride – Window stride. It must be a multiple of block stride. 
  1094.     padding – Mock parameter to keep the CPU interface compatibility. It must be (0,0). 
  1095.     scale0 – Coefficient of the detection window increase. 
  1096.     group_threshold – Coefficient to regulate the similarity threshold(相似性阈值). When detected, some  
  1097.     objects can be covered by many rectangles. 0 means not to perform groupin 
  1098.     */  
  1099. {  
  1100.     double scale = 1.;  
  1101.     int levels = 0;  
  1102.   
  1103.     vector<double> levelScale;  
  1104.     //要使检测窗口的尺度变大有两种方案,法一:图像尺寸不变,增大检测窗口的大小;法二:反过来,检测窗口不变,缩小图片  
  1105.     //这里使用的正是第二种方法  
  1106.     for( levels = 0; levels < nlevels; levels++ )    //默认值:64  
  1107.     {  
  1108.         levelScale.push_back(scale);  
  1109.         if( cvRound(img.cols/scale) < winSize.width ||   // 小于64层尺度的尺度数由是由图形的尺寸 和 scale0 决定的,  
  1110.             cvRound(img.rows/scale) < winSize.height || //当图像缩放到已经小于检测窗口时就已经不能在增加尺度了  
  1111.             scale0 <= 1 )  
  1112.             break;  
  1113.         scale *= scale0;  
  1114.     }  
  1115.     levels = std::max(levels, 1);  
  1116.     levelScale.resize(levels);  
  1117.   
  1118.     std::vector allCandidates;  
  1119.     std::vector<double> tempScales;  
  1120.     std::vector<double> tempWeights;  
  1121.     std::vector<double> foundScales;  
  1122.     Mutex mtx;  
  1123.     //[begin,end)  
  1124.     //TBB,参考 http://blog.csdn.net/zoufeiyy/article/details/1887579  
  1125.     parallel_for_(Range(0, (int)levelScale.size()),  
  1126.                  HOGInvoker(this, img, hitThreshold, winStride, padding, &levelScale[0], &allCandidates, &mtx, &tempWeights, &tempScales));  
  1127.   
  1128.     std::copy(tempScales.begin(), tempScales.end(), back_inserter(foundScales));//把tempScales的内容添加到 foundScales 后面  
  1129.     foundLocations.clear();  
  1130.     std::copy(allCandidates.begin(), allCandidates.end(), back_inserter(foundLocations));  
  1131.     foundWeights.clear();  
  1132.     std::copy(tempWeights.begin(), tempWeights.end(), back_inserter(foundWeights));  
  1133.   
  1134.     if ( useMeanshiftGrouping )  
  1135.     {  
  1136.         groupRectangles_meanshift(foundLocations, foundWeights, foundScales, finalThreshold, winSize);  
  1137.     }  
  1138.     else  
  1139.     {  
  1140.         groupRectangles(foundLocations, (int)finalThreshold, 0.2);  
  1141.     }  
  1142. }  
  1143.   
  1144. void HOGDescriptor::detectMultiScale(const Mat& img, vector& foundLocations,  
  1145.                                      double hitThreshold, Size winStride, Size padding,  
  1146.                                      double scale0, double finalThreshold, bool useMeanshiftGrouping) const  
  1147. {  
  1148.     vector<double> foundWeights;  
  1149.     detectMultiScale(img, foundLocations, foundWeights, hitThreshold, winStride,  
  1150.                      padding, scale0, finalThreshold, useMeanshiftGrouping);  
  1151. }  
  1152.   
  1153. typedef RTTIImpl HOGRTTI;  
  1154.   
  1155. CvType hog_type( CV_TYPE_NAME_HOG_DESCRIPTOR, HOGRTTI::isInstance,  
  1156.                  HOGRTTI::release, HOGRTTI::read, HOGRTTI::write, HOGRTTI::clone);  
  1157.   
  1158. vector<float> HOGDescriptor::getDefaultPeopleDetector()  
  1159. {  
  1160.     static const float detector[] = {  
  1161.        0.05359386f, -0.14721455f, -0.05532170f, 0.05077307f,  
  1162.        0.11547081f, -0.04268804f, 0.04635834f, -0.05468199f, 0.08232084f,  
  1163.        0.10424068f, -0.02294518f, 0.01108519f, 0.01378693f, 0.11193510f,  
  1164.        0.01268418f, 0.08528346f, -0.06309239f, 0.13054633f, 0.08100729f,  
  1165.        -0.05209739f, -0.04315529f, 0.09341384f, 0.11035026f, -0.07596218f,  
  1166.        -0.05517511f, -0.04465296f, 0.02947334f, 0.04555536f,  
  1167.        -3.55954492e-003f, 0.07818956f, 0.07730991f, 0.07890715f, 0.06222893f,  
  1168.        0.09001380f, -0.03574381f, 0.03414327f, 0.05677258f, -0.04773581f,  
  1169.        0.03746637f, -0.03521175f, 0.06955440f, -0.03849038f, 0.01052293f,  
  1170.        0.01736112f, 0.10867710f, 0.08748853f, 3.29739624e-003f, 0.10907028f,  
  1171.        0.07913758f, 0.10393070f, 0.02091867f, 0.11594022f, 0.13182420f,  
  1172.        0.09879354f, 0.05362710f, -0.06745391f, -7.01260753e-003f,  
  1173.        5.24702156e-003f, 0.03236255f, 0.01407916f, 0.02207983f, 0.02537322f,  
  1174.        0.04547948f, 0.07200756f, 0.03129894f, -0.06274468f, 0.02107014f,  
  1175.        0.06035208f, 0.08636236f, 4.53164103e-003f, 0.02193363f, 0.02309801f,  
  1176.        0.05568166f, -0.02645093f, 0.04448695f, 0.02837519f, 0.08975694f,  
  1177.        0.04461516f, 0.08975355f, 0.07514391f, 0.02306982f, 0.10410084f,  
  1178.        0.06368385f, 0.05943464f, 4.58420580e-003f, 0.05220337f, 0.06675851f,  
  1179.        0.08358569f, 0.06712101f, 0.06559004f, -0.03930482f, -9.15936660e-003f,  
  1180.        -0.05897915f, 0.02816453f, 0.05032348f, 0.06780671f, 0.03377650f,  
  1181.        -6.09417039e-004f, -0.01795146f, -0.03083684f, -0.01302475f,  
  1182.        -0.02972313f, 7.88706727e-003f, -0.03525961f, -2.50397739e-003f,  
  1183.        0.05245084f, 0.11791293f, -0.02167498f, 0.05299332f, 0.06640524f,  
  1184.        0.05190265f, -8.27316567e-003f, 0.03033127f, 0.05842173f,  
  1185.        -4.01050318e-003f, -6.25105947e-003f, 0.05862958f, -0.02465461f,  
  1186.        0.05546781f, -0.08228195f, -0.07234028f, 0.04640540f, -0.01308254f,  
  1187.        -0.02506191f, 0.03100746f, -0.04665651f, -0.04591486f, 0.02949927f,  
  1188.        0.06035462f, 0.02244646f, -0.01698639f, 0.01040041f, 0.01131170f,  
  1189.        0.05419579f, -0.02130277f, -0.04321722f, -0.03665198f, 0.01126490f,  
  1190.        -0.02606488f, -0.02228328f, -0.02255680f, -0.03427236f,  
  1191.        -7.75165204e-003f, -0.06195229f, 8.21638294e-003f, 0.09535975f,  
  1192.        -0.03709979f, -0.06942501f, 0.14579427f, -0.05448192f, -0.02055904f,  
  1193.        0.05747357f, 0.02781788f, -0.07077577f, -0.05178314f, -0.10429011f,  
  1194.        -0.11235505f, 0.07529039f, -0.07559302f, -0.08786739f, 0.02983843f,  
  1195.        0.02667585f, 0.01382199f, -0.01797496f, -0.03141199f, -0.02098101f,  
  1196.        0.09029204f, 0.04955018f, 0.13718739f, 0.11379953f, 1.80019124e-003f,  
  1197.        -0.04577610f, -1.11108483e-003f, -0.09470536f, -0.11596080f,  
  1198.        0.04489342f, 0.01784211f, 3.06850672e-003f, 0.10781866f,  
  1199.        3.36498418e-003f, -0.10842580f, -0.07436839f, -0.10535070f,  
  1200.        -0.01866805f, 0.16057891f, -5.07316366e-003f, -0.04295658f,  
  1201.        -5.90488780e-003f, 8.82003549e-003f, -0.01492646f, -0.05029279f,  
  1202.        -0.12875880f, 8.78831954e-004f, -0.01297184f, -0.07592774f,  
  1203.        -0.02668831f, -6.93787413e-004f, 0.02406698f, -0.01773298f,  
  1204.        -0.03855745f, -0.05877856f, 0.03259695f, 0.12826584f, 0.06292590f,  
  1205.        -4.10733931e-003f, 0.10996531f, 0.01332991f, 0.02088735f, 0.04037504f,  
  1206.        -0.05210760f, 0.07760046f, 0.06399347f, -0.05751930f, -0.10053057f,  
  1207.        0.07505023f, -0.02139782f, 0.01796176f, 2.34400877e-003f, -0.04208319f,  
  1208.        0.07355055f, 0.05093350f, -0.02996780f, -0.02219072f, 0.03355330f,  
  1209.        0.04418742f, -0.05580705f, -0.05037573f, -0.04548179f, 0.01379514f,  
  1210.        0.02150671f, -0.02194211f, -0.13682702f, 0.05464972f, 0.01608082f,  
  1211.        0.05309116f, 0.04701022f, 1.33690401e-003f, 0.07575664f, 0.09625306f,  
  1212.        8.92647635e-003f, -0.02819123f, 0.10866830f, -0.03439325f,  
  1213.        -0.07092371f, -0.06004780f, -0.02712298f, -7.07467366e-003f,  
  1214.        -0.01637020f, 0.01336790f, -0.10313606f, 0.04906582f, -0.05732445f,  
  1215.        -0.02731079f, 0.01042235f, -0.08340668f, 0.03686501f, 0.06108340f,  
  1216.        0.01322748f, -0.07809529f, 0.03774724f, -0.03413248f, -0.06096525f,  
  1217.        -0.04212124f, -0.07982176f, -1.25973229e-003f, -0.03045501f,  
  1218.        -0.01236493f, -0.06312395f, 0.04789570f, -0.04602066f, 0.08576570f,  
  1219.        0.02521080f, 0.02988098f, 0.10314583f, 0.07060035f, 0.04520544f,  
  1220.        -0.04426654f, 0.13146530f, 0.08386490f, 0.02164590f, -2.12280243e-003f,  
  1221.        -0.03686353f, -0.02074944f, -0.03829959f, -0.01530596f, 0.02689708f,  
  1222.        0.11867401f, -0.06043470f, -0.02785023f, -0.04775074f, 0.04878745f,  
  1223.        0.06350956f, 0.03494788f, 0.01467400f, 1.17890188e-003f, 0.04379614f,  
  1224.        2.03681854e-003f, -0.03958609f, -0.01072688f, 6.43705716e-003f,  
  1225.        0.02996500f, -0.03418507f, -0.01960307f, -0.01219154f,  
  1226.        -4.37000440e-003f, -0.02549453f, 0.02646318f, -0.01632513f,  
  1227.        6.46516960e-003f, -0.01929734f, 4.78711911e-003f, 0.04962371f,  
  1228.        0.03809111f, 0.07265724f, 0.05758125f, -0.03741554f, 0.01648608f,  
  1229.        -8.45285598e-003f, 0.03996826f, -0.08185477f, 0.02638875f,  
  1230.        -0.04026615f, -0.02744674f, -0.04071517f, 1.05096330e-003f,  
  1231.        -0.04741232f, -0.06733172f, 8.70434940e-003f, -0.02192543f,  
  1232.        1.35350740e-003f, -0.03056974f, -0.02975521f, -0.02887780f,  
  1233.        -0.01210713f, -0.04828526f, -0.09066251f, -0.09969629f, -0.03665164f,  
  1234.        -8.88111943e-004f, -0.06826669f, -0.01866150f, -0.03627640f,  
  1235.        -0.01408288f, 0.01874239f, -0.02075835f, 0.09145175f, -0.03547291f,  
  1236.        0.05396780f, 0.04198981f, 0.01301925f, -0.03384354f, -0.12201976f,  
  1237.        0.06830920f, -0.03715654f, 9.55848210e-003f, 5.05685573e-003f,  
  1238.        0.05659294f, 3.90764466e-003f, 0.02808490f, -0.05518097f, -0.03711621f,  
  1239.        -0.02835565f, -0.04420464f, -0.01031947f, 0.01883466f,  
  1240.        -8.49525444e-003f, -0.09419250f, -0.01269387f, -0.02133371f,  
  1241.        -0.10190815f, -0.07844430f, 2.43644323e-003f, -4.09610150e-003f,  
  1242.        0.01202551f, -0.06452291f, -0.10593818f, -0.02464746f, -0.02199699f,  
  1243.        -0.07401930f, 0.07285886f, 8.87513801e-004f, 9.97662079e-003f,  
  1244.        8.46779719e-003f, 0.03730333f, -0.02905126f, 0.03573337f, -0.04393689f,  
  1245.        -0.12014472f, 0.03176554f, -2.76015815e-003f, 0.10824566f, 0.05090732f,  
  1246.        -3.30179278e-003f, -0.05123822f, 5.04784798e-003f, -0.05664124f,  
  1247.        -5.99415926e-003f, -0.05341901f, -0.01221393f, 0.01291318f,  
  1248.        9.91760660e-003f, -7.56987557e-003f, -0.06193124f, -2.24549137e-003f,  
  1249.        0.01987562f, -0.02018840f, -0.06975540f, -0.06601523f, -0.03349112f,  
  1250.        -0.08910118f, -0.03371435f, -0.07406893f, -0.02248047f, -0.06159951f,  
  1251.        2.77751544e-003f, -0.05723337f, -0.04792468f, 0.07518548f,  
  1252.        2.77279224e-003f, 0.04211938f, 0.03100502f, 0.05278448f, 0.03954679f,  
  1253.        -0.03006846f, -0.03851741f, -0.02792403f, -0.02875333f, 0.01531280f,  
  1254.        0.02186953f, -0.01989829f, 2.50679464e-003f, -0.10258728f,  
  1255.        -0.04785743f, -0.02887216f, 3.85063468e-003f, 0.01112236f,  
  1256.        8.29218887e-003f, -0.04822981f, -0.04503597f, -0.03713100f,  
  1257.        -0.06988008f, -0.11002295f, -2.69209221e-003f, 1.85383670e-003f,  
  1258.        -0.05921049f, -0.06105053f, -0.08458050f, -0.04527602f,  
  1259.        8.90329306e-004f, -0.05875023f, -2.68602883e-003f, -0.01591195f,  
  1260.        0.03631859f, 0.05493166f, 0.07300330f, 5.53333294e-003f, 0.06400407f,  
  1261.        0.01847740f, -5.76280477e-003f, -0.03210877f, 4.25160583e-003f,  
  1262.        0.01166520f, -1.44864211e-003f, 0.02253744f, -0.03367080f, 0.06983195f,  
  1263.        -4.22323542e-003f, -8.89401045e-003f, -0.07943393f, 0.05199728f,  
  1264.        0.06065201f, 0.04133492f, 1.44032843e-003f, -0.09585235f, -0.03964731f,  
  1265.        0.04232114f, 0.01750465f, -0.04487902f, -7.59733608e-003f, 0.02011171f,  
  1266.        0.04673622f, 0.09011173f, -0.07869188f, -0.04682482f, -0.05080139f,  
  1267.        -3.99383716e-003f, -0.05346331f, 0.01085723f, -0.03599333f,  
  1268.        -0.07097908f, 0.03551549f, 0.02680387f, 0.03471529f, 0.01790393f,  
  1269.        0.05471273f, 9.62048303e-003f, -0.03180215f, 0.05864431f, 0.02330614f,  
  1270.        0.01633144f, -0.05616681f, -0.10245429f, -0.08302189f, 0.07291322f,  
  1271.        -0.01972590f, -0.02619633f, -0.02485327f, -0.04627592f,  
  1272.        1.48853404e-003f, 0.05514185f, -0.01270860f, -0.01948900f, 0.06373586f,  
  1273.        0.05002292f, -0.03009798f, 8.76216311e-003f, -0.02474238f,  
  1274.        -0.05504891f, 1.74034527e-003f, -0.03333667f, 0.01524987f, 0.11663762f,  
  1275.        -1.32344989e-003f, -0.06608453f, 0.05687166f, -6.89525274e-004f,  
  1276.        -0.04402352f, 0.09450210f, -0.04222684f, -0.05360983f, 0.01779531f,  
  1277.        0.02561388f, -0.11075410f, -8.77790991e-003f, -0.01099504f,  
  1278.        -0.10380266f, 0.03103457f, -0.02105741f, -0.07371717f, 0.05146710f,  
  1279.        0.10581432f, -0.08617968f, -0.02892107f, 0.01092199f, 0.14551543f,  
  1280.        -2.24320893e-003f, -0.05818033f, -0.07390742f, 0.05701261f,  
  1281.        0.12937020f, -0.04986651f, 0.10182415f, 0.05028650f, 0.12515625f,  
  1282.        0.09175041f, 0.06404983f, 0.01523394f, 0.09460562f, 0.06106631f,  
  1283.        -0.14266998f, -0.02926703f, 0.02762171f, 0.02164151f,  
  1284.        -9.58488265e-004f, -0.04231362f, -0.09866509f, 0.04322244f,  
  1285.        0.05872034f, -0.04838847f, 0.06319253f, 0.02443798f, -0.03606876f,  
  1286.        9.38737206e-003f, 0.04289991f, -0.01027411f, 0.08156885f, 0.08751175f,  
  1287.        -0.13191354f, 8.16054735e-003f, -0.01452161f, 0.02952677f, 0.03615945f,  
  1288.        -2.09128903e-003f, 0.02246693f, 0.09623287f, 0.09412123f, -0.02924758f,  
  1289.        -0.07815186f, -0.02203079f, -2.02566991e-003f, 0.01094733f,  
  1290.        -0.01442332f, 0.02838561f, 0.11882371f, 7.28798332e-003f, -0.10345965f,  
  1291.        0.07561217f, -0.02049661f, 4.44177445e-003f, 0.01609347f, -0.04893158f,  
  1292.        -0.08758243f, -7.67420698e-003f, 0.08862378f, 0.06098121f, 0.06565887f,  
  1293.        7.32981879e-003f, 0.03558407f, -0.03874352f, -0.02490055f,  
  1294.        -0.06771075f, 0.09939223f, -0.01066077f, 0.01382995f, -0.07289080f,  
  1295.        7.47184316e-003f, 0.10621431f, -0.02878659f, 0.02383525f, -0.03274646f,  
  1296.        0.02137008f, 0.03837290f, 0.02450992f, -0.04296818f, -0.02895143f,  
  1297.        0.05327370f, 0.01499020f, 0.04998732f, 0.12938657f, 0.09391870f,  
  1298.        0.04292390f, -0.03359194f, -0.06809492f, 0.01125796f, 0.17290455f,  
  1299.        -0.03430733f, -0.06255233f, -0.01813114f, 0.11726857f, -0.06127599f,  
  1300.        -0.08677909f, -0.03429872f, 0.04684938f, 0.08161420f, 0.03538774f,  
  1301.        0.01833884f, 0.11321855f, 0.03261845f, -0.04826299f, 0.01752407f,  
  1302.        -0.01796414f, -0.10464549f, -3.30041884e-003f, 2.29343961e-004f,  
  1303.        0.01457292f, -0.02132982f, -0.02602923f, -9.87351313e-003f,  
  1304.        0.04273872f, -0.02103316f, -0.07994065f, 0.02614958f, -0.02111666f,  
  1305.        -0.06964913f, -0.13453490f, -0.06861878f, -6.09341264e-003f,  
  1306.        0.08251446f, 0.15612499f, 2.46531400e-003f, 8.88424646e-003f,  
  1307.        -0.04152999f, 0.02054853f, 0.05277953f, -0.03087788f, 0.02817579f,  
  1308.        0.13939077f, 0.07641046f, -0.03627627f, -0.03015098f, -0.04041540f,  
  1309.        -0.01360690f, -0.06227205f, -0.02738223f, 0.13577610f, 0.15235767f,  
  1310.        -0.05392922f, -0.11175954f, 0.02157129f, 0.01146481f, -0.05264937f,  
  1311.        -0.06595174f, -0.02749175f, 0.11812254f, 0.17404149f, -0.06137035f,  
  1312.        -0.11003478f, -0.01351621f, -0.01745916f, -0.08577441f, -0.04469909f,  
  1313.        -0.06106115f, 0.10559758f, 0.20806813f, -0.09174948f, 7.09621934e-004f,  
  1314.        0.03579374f, 0.07215115f, 0.02221742f, 0.01827742f, -7.90785067e-003f,  
  1315.        0.01489554f, 0.14519960f, -0.06425831f, 0.02990399f, -1.80181325e-003f,  
  1316.        -0.01401528f, -0.04171134f, -3.70530109e-003f, -0.09090481f,  
  1317.        0.09520713f, 0.08845516f, -0.02651753f, -0.03016730f, 0.02562448f,  
  1318.        0.03563816f, -0.03817881f, 0.01433385f, 0.02256983f, 0.02872120f,  
  1319.        0.01001934f, -0.06332260f, 0.04338406f, 0.07001807f, -0.04705722f,  
  1320.        -0.07318907f, 0.02630457f, 0.03106382f, 0.06648342f, 0.10913180f,  
  1321.        -0.01630815f, 0.02910308f, 0.02895109f, 0.08040254f, 0.06969310f,  
  1322.        0.06797734f, 6.08639978e-003f, 4.16588830e-003f, 0.08926726f,  
  1323.        -0.03123648f, 0.02700146f, 0.01168734f, -0.01631594f, 4.61015804e-003f,  
  1324.        8.51359498e-003f, -0.03544224f, 0.03571994f, 4.29766066e-003f,  
  1325.        -0.01970077f, -8.79793242e-003f, 0.09607988f, 0.01544222f,  
  1326.        -0.03923707f, 0.07308586f, 0.06061262f, 1.31683104e-004f,  
  1327.        -7.98222050e-003f, 0.02399261f, -0.06084389f, -0.02743429f,  
  1328.        -0.05475523f, -0.04131311f, 0.03559756f, 0.03055342f, 0.02981433f,  
  1329.        0.14860515f, 0.01766787f, 0.02945257f, 0.04898238f, 0.01026922f,  
  1330.        0.02811658f, 0.08267091f, 0.02732154f, -0.01237693f, 0.11760156f,  
  1331.        0.03802063f, -0.03309754f, 5.24957618e-003f, -0.02460510f, 0.02691451f,  
  1332.        0.05399988f, -0.10133506f, 0.06385437f, -0.01818005f, 0.02259503f,  
  1333.        0.03573135f, 0.01042848f, -0.04153402f, -0.04043029f, 0.01643575f,  
  1334.        0.08326677f, 4.61383024e-004f, -0.05308095f, -0.08536223f,  
  1335.        -1.61011645e-003f, -0.02163720f, -0.01783352f, 0.03859637f,  
  1336.        0.08498885f, -0.01725216f, 0.08625131f, 0.10995087f, 0.09177644f,  
  1337.        0.08498347f, 0.07646490f, 0.05580502f, 0.02693516f, 0.09996913f,  
  1338.        0.09070327f, 0.06667200f, 0.05873008f, -0.02247842f, 0.07772321f,  
  1339.        0.12408436f, 0.12629253f, -8.41997913e-004f, 0.01477783f, 0.09165990f,  
  1340.        -2.98401713e-003f, -0.06466447f, -0.07057302f, 2.09516948e-004f,  
  1341.        0.02210209f, -0.02158809f, -0.08602506f, -0.02284836f,  
  1342.        4.01876355e-003f, 9.56660323e-003f, -0.02073978f, -0.04635138f,  
  1343.        -7.59423291e-003f, -0.01377393f, -0.04559359f, -0.13284740f,  
  1344.        -0.08671406f, -0.03654395f, 0.01142869f, 0.03287891f, -0.04392983f,  
  1345.        0.06142959f, 0.17710890f, 0.10385257f, 0.01329137f, 0.10067633f,  
  1346.        0.12450829f, -0.04476709f, 0.09049144f, 0.04589312f, 0.11167907f,  
  1347.        0.08587538f, 0.04767583f, 1.67188141e-003f, 0.02359802f, -0.03808852f,  
  1348.        0.03126272f, -0.01919029f, -0.05698918f, -0.02365112f, -0.06519032f,  
  1349.        -0.05599358f, -0.07097308f, -0.03301812f, -0.04719102f, -0.02566297f,  
  1350.        0.01324074f, -0.09230672f, -0.05518232f, -0.04712864f, -0.03380903f,  
  1351.        -0.06719479f, 0.01183908f, -0.09326738f, 0.01642865f, 0.03789867f,  
  1352.        -6.61567831e-003f, 0.07796386f, 0.07246574f, 0.04706347f, -0.02523437f,  
  1353.        -0.01696830f, -0.08068866f, 0.06030888f, 0.10527060f, -0.06611756f,  
  1354.        0.02977346f, 0.02621830f, 0.01913855f, -0.08479366f, -0.06322418f,  
  1355.        -0.13570616f, -0.07644490f, 9.31900274e-003f, -0.08095149f,  
  1356.        -0.10197903f, -0.05204025f, 0.01413151f, -0.07800411f, -0.01885122f,  
  1357.        -0.07509381f, -0.10136326f, -0.05212355f, -0.09944065f,  
  1358.        -1.33606605e-003f, -0.06342617f, -0.04178550f, -0.12373723f,  
  1359.        -0.02832736f, -0.06057501f, 0.05830070f, 0.07604282f, -0.06462587f,  
  1360.        8.02447461e-003f, 0.11580125f, 0.12332212f, 0.01978462f,  
  1361.        -2.72378162e-003f, 0.05850752f, -0.04674481f, 0.05148062f,  
  1362.        -2.62542837e-003f, 0.11253355f, 0.09893716f, 0.09785093f, -0.04659257f,  
  1363.        -0.01102429f, -0.07002308f, 0.03088913f, -0.02565549f, -0.07671449f,  
  1364.        3.17443861e-003f, -0.10783514f, -0.02314270f, -0.11089555f,  
  1365.        -0.01024768f, 0.03116021f, -0.04964825f, 0.02281825f, 5.50005678e-003f,  
  1366.        -0.08427856f, -0.14685495f, -0.07719755f, -0.13342668f, -0.04525511f,  
  1367.        -0.09914210f, 0.02588859f, 0.03469279f, 0.04664020f, 0.11688190f,  
  1368.        0.09647275f, 0.10857815f, -0.01448726f, 0.04299758f, -0.06763151f,  
  1369.        1.33257592e-003f, 0.14331576f, 0.07574340f, 0.09166205f, 0.05674926f,  
  1370.        0.11325553f, -0.01106494f, 0.02062161f, -0.11484840f, -0.07492137f,  
  1371.        -0.02864293f, -0.01275638f, -0.06946032f, -0.10101652f, -0.04113498f,  
  1372.        -0.02214783f, -0.01273942f, -0.07480393f, -0.10556041f, -0.07622112f,  
  1373.        -0.09988393f, -0.11453961f, -0.12073903f, -0.09412795f, -0.07146588f,  
  1374.        -0.04054537f, -0.06127083f, 0.04221122f, 0.07688113f, 0.04099256f,  
  1375.        0.12663734f, 0.14683802f, 0.21761774f, 0.12525328f, 0.18431792f,  
  1376.        -1.66402373e-003f, 2.37777247e-003f, 0.01445475f, 0.03509416f,  
  1377.        0.02654697f, 0.01716739f, 0.05374011f, 0.02944174f, 0.11323927f,  
  1378.        -0.01485456f, -0.01611330f, -1.85554172e-003f, -0.01708549f,  
  1379.        -0.05435753f, -0.05302101f, 0.05260378f, -0.03582945f,  
  1380.        -3.42867890e-004f, 1.36076682e-003f, -0.04436073f, -0.04228432f,  
  1381.        0.03281291f, -0.05480836f, -0.10197772f, -0.07206279f, -0.10741059f,  
  1382.        -0.02366946f, 0.10278475f, -2.74783419e-003f, -0.03242477f,  
  1383.        0.02308955f, 0.02835869f, 0.10348799f, 0.19580358f, 0.10252027f,  
  1384.        0.08039929f, 0.05525554f, -0.13250865f, -0.14395352f, 3.13586881e-003f,  
  1385.        -0.03387071f, 8.94669443e-003f, 0.05406157f, -4.97324532e-003f,  
  1386.        -0.01189114f, 2.82919413e-004f, -0.03901557f, -0.04898705f,  
  1387.        0.02164520f, -0.01382906f, -0.01850416f, 0.01869347f, -0.02450060f,  
  1388.        0.02291678f, 0.08196463f, 0.03309153f, -0.10629974f, 0.02473924f,  
  1389.        0.05344394f, -0.02404823f, -0.03243643f, -5.55244600e-003f,  
  1390.        -0.08009996f, 0.02811539f, 0.04235742f, 0.01859004f, 0.04902123f,  
  1391.        -0.01438252f, -0.01526853f, 0.02044195f, -0.05008660f, 0.04244113f,  
  1392.        0.07611816f, 0.04950470f, -0.06020549f, -4.26026015e-003f, 0.13133512f,  
  1393.        -0.01438738f, -0.01958807f, -0.04044152f, -0.12425045f,  
  1394.        2.84353318e-003f, -0.05042776f, -0.09121484f, 7.34345755e-003f,  
  1395.        0.09388847f, 0.11800314f, 4.72295098e-003f, 4.44378285e-003f,  
  1396.        -0.07984917f, -0.03613737f, 0.04490915f, -0.02246483f, 0.04681071f,  
  1397.        0.05240871f, 0.02157206f, -0.04603431f, -0.01197929f, -0.02748779f,  
  1398.        0.13621049f, 0.08812155f, -0.07802048f, 4.86458559e-003f, -0.01598836f,  
  1399.        0.01024450f, -0.03463517f, -0.02304239f, -0.08692665f, 0.06655128f,  
  1400.        0.05785803f, -0.12640759f, 0.02307472f, 0.07337402f, 0.07525434f,  
  1401.        0.04943763f, -0.02241034f, -0.09978238f, 0.14487994f, -0.06570521f,  
  1402.        -0.07855482f, 0.02830222f, -5.29603509e-004f, -0.04669895f,  
  1403.        -0.11822784f, -0.12246452f, -0.15365660f, -0.02969127f, 0.08078201f,  
  1404.        0.13512598f, 0.11505685f, 0.04740673f, 0.01376022f, -0.05852978f,  
  1405.        -0.01537809f, -0.05541119f, 0.02491065f, -0.02870786f, 0.02760978f,  
  1406.        0.23836176f, 0.22347429f, 0.10306466f, -0.06919070f, -0.10132039f,  
  1407.        -0.20198342f, -0.05040560f, 0.27163076f, 0.36987007f, 0.34540465f,  
  1408.        0.29095781f, 0.05649706f, 0.04125737f, 0.07505883f, -0.02737836f,  
  1409.        -8.43431335e-003f, 0.07368195f, 0.01653876f, -0.09402955f,  
  1410.        -0.09574359f, 0.01474337f, -0.07128561f, -0.03460737f, 0.11438941f,  
  1411.        0.13752601f, -0.06385452f, -0.06310338f, 8.19548313e-003f, 0.11622470f,  
  1412.        5.05133113e-003f, -0.07602754f, 0.06695660f, 0.25723928f, 0.09037900f,  
  1413.        0.28826267f, 0.13165380f, -0.05312614f, -0.02137198f, -0.03442232f,  
  1414.        -0.06255679f, 0.03899667f, 0.18391028f, 0.26016650f, 0.03374462f,  
  1415.        0.01860465f, 0.19077586f, 0.18160543f, 3.43634398e-003f, -0.03036782f,  
  1416.        0.19683038f, 0.35378191f, 0.24968483f, -0.03222649f, 0.28972381f,  
  1417.        0.43091634f, 0.30778357f, 0.02335266f, -0.09877399f, -6.85245218e-003f,  
  1418.        0.08945240f, -0.08150686f, 0.02792493f, 0.24806842f, 0.17338486f,  
  1419.        0.06231801f, -0.10432383f, -0.16653322f, -0.13197899f, -0.08531576f,  
  1420.        -0.19271527f, -0.13536365f, 0.22240199f, 0.39219588f, 0.26597717f,  
  1421.        -0.01231649f, 0.01016179f, 0.13379875f, 0.12018334f, -0.04852953f,  
  1422.        -0.07915270f, 0.07036012f, 3.87723115e-003f, -0.06126805f,  
  1423.        -0.15015170f, -0.11406515f, -0.08556531f, -0.07429333f, -0.16115491f,  
  1424.        0.13214062f, 0.25691369f, 0.05697750f, 0.06861912f, -6.02903729e-003f,  
  1425.        -7.94562511e-003f, 0.04799571f, 0.06695165f, -0.01926842f, 0.06206308f,  
  1426.        0.13450983f, -0.06381495f, -2.98370165e-003f, -0.03482971f,  
  1427.        7.53991678e-003f, 0.03895611f, 0.11464261f, 0.01669971f,  
  1428.        8.27818643e-003f, -7.49160210e-003f, -0.11712562f, -0.10650621f,  
  1429.        -0.10353880f, -0.04994106f, -7.65618810e-004f, 0.03023767f,  
  1430.        -0.04759270f, -0.07302686f, -0.05825012f, -0.13156348f, -0.10639747f,  
  1431.        -0.19393684f, -0.09973683f, -0.07918908f, 4.63177625e-004f,  
  1432.        -6.61382044e-004f, 0.15853868f, 0.08561199f, -0.07660093f,  
  1433.        -0.08015265f, -0.06164073f, 0.01882577f, -7.29908410e-004f,  
  1434.        0.06840892f, 0.03843764f, 0.20274927f, 0.22028814f, -5.26101235e-003f,  
  1435.        0.01452435f, -0.06331623f, 0.02865064f, 0.05673740f, 0.12171564f,  
  1436.        0.03837196f, 0.03555467f, -0.02662914f, -0.10280123f, -0.06526285f,  
  1437.        -0.11066351f, -0.08988424f, -0.10103678f, 8.10526591e-003f,  
  1438.        5.95238712e-003f, 0.02617721f, -0.01705742f, -0.10897956f,  
  1439.        -0.08004991f, -0.11271993f, -0.06185647f, -0.06103712f, 0.01597041f,  
  1440.        -0.05923606f, 0.09410726f, 0.22858568f, 0.03263380f, 0.06772990f,  
  1441.        -0.09003516f, 0.01017870f, 0.01931688f, 0.08628357f, -0.01430009f,  
  1442.        0.10954945f, 0.16612452f, -0.02434544f, -0.03310068f, -0.04236627f,  
  1443.        0.01212392f, -6.15046406e-003f, 0.06954194f, 0.03015283f, 0.01787957f,  
  1444.        0.02781667f, -0.05561153f, -8.96244217e-003f, -0.04971489f,  
  1445.        0.07510284f, 0.01775282f, 0.05889897f, -0.07981427f, 0.03647643f,  
  1446.        -3.73833324e-003f, -0.08894575f, -0.06429435f, -0.08068276f,  
  1447.        0.03567704f, -0.07131936f, -7.21910037e-003f, -0.09566668f,  
  1448.        0.17886090f, 0.14911725f, 0.02070032f, -0.05017120f, -0.04992622f,  
  1449.        0.01570143f, -0.09906903f, 0.06456193f, 0.15329507f, 0.18820767f,  
  1450.        0.11689861f, -0.01178513f, -0.02225163f, -0.01905318f, 0.10271224f,  
  1451.        -7.27029052e-003f, 0.11664233f, 0.14796902f, 0.07771893f, 0.02400013f,  
  1452.        -0.05361797f, -0.01972888f, 0.01376177f, 0.06740040f, -0.06525395f,  
  1453.        0.05726178f, -0.02404981f, -0.14018567f, -0.02074987f, -0.04621970f,  
  1454.        -0.04688627f, -0.01842059f, 0.07722727f, -0.04852883f, 0.01529004f,  
  1455.        -0.19639495f, 0.10817073f, 0.03795860f, -0.09435206f, -0.07984378f,  
  1456.        -0.03383440f, 0.11081333f, 0.02237366f, 0.12703256f, 0.21613893f,  
  1457.        0.02918790f, 4.66472283e-003f, -0.10274266f, -0.04854131f,  
  1458.        -3.46305710e-003f, 0.08652268f, 0.02251546f, 0.09636052f, 0.17180754f,  
  1459.        -0.09272388f, 4.59174305e-004f, -0.11723048f, -0.12210111f,  
  1460.        -0.15547538f, 0.07218186f, -0.05297846f, 0.03779940f, 0.05150875f,  
  1461.        -0.03802310f, 0.03870645f, -0.15250699f, -0.08696499f, -0.02021560f,  
  1462.        0.04118926f, -0.15177974f, 0.01577647f, 0.10249301f, 7.50041893e-003f,  
  1463.        0.01721806f, -0.06828983f, -0.02397596f, -0.06598977f, -0.04317593f,  
  1464.        -0.08064980f, 6.66632550e-003f, 0.03333484f, 0.07093620f, 0.08231064f,  
  1465.        -0.06577903f, -0.06698844f, -0.06984019f, -0.06508023f, -0.14145090f,  
  1466.        -0.02393239f, 0.06485303f, 8.83263443e-003f, 0.09251080f, -0.07557579f,  
  1467.        -0.05067699f, -0.09798748f, -0.06703258f, -0.14056294f, 0.03245994f,  
  1468.        0.12554143f, 0.01761621f, 0.12980327f, -0.04081950f, -0.11906909f,  
  1469.        -0.14813015f, -0.08376863f, -0.12200681f, 0.04988137f, 0.05424247f,  
  1470.        -3.90952639e-003f, 0.03255733f, -0.12717837f, -0.07461493f,  
  1471.        -0.05703964f, -0.01736189f, -0.08026433f, -0.05433894f, -0.01719359f,  
  1472.        0.02886275f, 0.01772653f, -0.09163518f, 3.57789593e-003f, -0.10129993f,  
  1473.        -0.02653764f, -0.08131415f, -0.03847986f, -7.62157550e-004f,  
  1474.        0.06486648f, 0.19675669f, -0.04919156f, -0.07059129f, -0.04857785f,  
  1475.        -0.01042383f, -0.08328653f, 0.03660302f, -0.03696846f, 0.04969259f,  
  1476.        0.08241162f, -0.12514858f, -0.06122676f, -0.03750202f,  
  1477.        6.52989605e-003f, -0.10247213f, 0.02568346f, 4.51781414e-003f,  
  1478.        -0.03734229f, -0.01131264f, -0.05412074f, 8.89345480e-004f,  
  1479.        -0.12388977f, -0.05959237f, -0.12418608f, -0.06151643f, -0.07310260f,  
  1480.        0.02441575f, 0.07023528f, -0.07548289f, -7.57147965e-004f,  
  1481.        -0.09061348f, -0.08112976f, -0.06920306f, 9.54394229e-003f,  
  1482.        -0.01219902f, 1.21273217e-003f, -8.88989680e-003f, -0.08309301f,  
  1483.        -0.04552661f, -0.10739882f, -0.05691034f, -0.13928030f, 0.09027749f,  
  1484.        0.15123098f, 0.03175976f, 0.17763577f, 3.29913251e-004f, 0.05151888f,  
  1485.        -0.09844074f, -0.09475287f, -0.08571247f, 0.16241577f, 0.19336018f,  
  1486.        8.57454538e-003f, 0.11474732f, -0.01493934f, 0.03352379f, -0.08966240f,  
  1487.        -0.02322310f, 0.02663568f, 0.05448750f, -0.03536883f, -0.07210463f,  
  1488.        -0.06807277f, -0.03121621f, -0.05932408f, -0.17282860f, -0.15873498f,  
  1489.        -0.04956378f, 0.01603377f, -0.12385946f, 0.13878587f, 0.21468069f,  
  1490.        0.13510075f, 0.20992437f, 0.08845878f, 0.08104013f, 0.03754176f,  
  1491.        0.12173114f, 0.11103114f, 0.10643122f, 0.13941477f, 0.11640384f,  
  1492.        0.14786847f, 0.01218238f, 0.01160753f, 0.03547940f, 0.08794311f,  
  1493.        -0.01695384f, -0.07692261f, -0.08236158f, 6.79194089e-003f,  
  1494.        -0.02458403f, 0.13022894f, 0.10953187f, 0.09857773f, 0.04735930f,  
  1495.        -0.04353498f, -0.15173385f, -0.17904443f, -0.10450364f, -0.13418166f,  
  1496.        -0.06633098f, -0.03170381f, -0.06839000f, -0.11350126f, -0.06983913f,  
  1497.        0.19083543f, 0.17604128f, 0.07730632f, 0.10022651f, 0.36428109f,  
  1498.        0.28291923f, 0.12688625f, 0.15942036f, 0.14064661f, -0.11201853f,  
  1499.        -0.13969108f, -0.09088077f, -0.14107047f, 0.05117374f,  
  1500.        -2.63348082e-003f, -0.10794610f, -0.09715455f, -0.05284977f,  
  1501.        0.01565668f, 0.05031200f, 0.07021113f, -0.02963028f, 0.01766960f,  
  1502.        0.08333644f, -0.03211382f, 4.90096770e-003f, 0.05186674f, -0.05045737f,  

你可能感兴趣的:(【图像】HOG)