• Hog实例


    1.计算Hog的特征得维度:

    #include <iostream>
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/objdetect/objdetect.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    
    using namespace std;
    using namespace cv;
    
    #define Posnum   2  //正样本个数
    #define Negnum 2    //负样本个数
    
    int main()
    {
    	char adpos[128], adneg[128];
    	HOGDescriptor hog(Size(64, 64), Size(16, 16), Size(8, 8), Size(8, 8), 3);//利用构造函数,给对象赋值。
    	int DescriptorDim;//HOG描述子的维数
    	Mat samFeatureMat, samLabelMat;
    	//依次读取正样本图片,生成HOG描述子
    	for (int i = 1; i <= Posnum; i++)
    	{
    		sprintf_s(adpos, "E:\VS2015Opencv\vs2015\project\picture\pos\%d.png", i);
    		Mat src = imread(adpos);//读取图片
    		resize(src, src, Size(64, 64));
    		vector<float> descriptors;//HOG描述子向量
    		hog.compute(src, descriptors);
    		if (i == 1)
    		{
    			DescriptorDim = descriptors.size();
    			samFeatureMat = Mat::zeros(Posnum + Negnum, DescriptorDim, CV_32FC1);
    			samLabelMat = Mat::zeros(Posnum + Negnum, 1, CV_32FC1);
    		}
    		for (int j = 0; j<DescriptorDim; j++)
    		{
    			samFeatureMat.at<float>(i - 1, j) = descriptors[j];
    			samLabelMat.at<float>(i - 1, 0) = 1;
    		}
    	}
    	//依次读取负样本图片,生成HOG描述子
    	for (int k = 1; k <= Negnum; k++)
    	{
    		sprintf_s(adneg, "E:\VS2015Opencv\vs2015\project\picture\neg\%d.png", k);
    		Mat src = imread(adneg);//读取图片
    		resize(src, src, Size(64, 64));
    		vector<float> descriptors;//HOG描述子向量
    		hog.compute(src, descriptors);
    		for (int l = 0; l<DescriptorDim; l++)
    		{
    			samFeatureMat.at<float>(k + Posnum - 1, l) = descriptors[l];
    			samLabelMat.at<float>(k + Posnum - 1, 0) = -1;
    		}
    	}
    	cout << "特征个数:" << samFeatureMat.rows << endl;
    	cout << "特征维度:" << samFeatureMat.cols << endl;
    	system("pause");
    	return 0;
    }
    

      这是一个很简单的代码;

    HOGDescriptor(Size _winSize, ---:窗口大小,即检测的范围大小,前面的64*128
            Size _blockSize,--- 前面的2*2的cell,即cell的数量,这里要填像素值Size(16,16)
            Size _blockStride,---每次block移动的步长,以像素计,为一个cell像素块大小
                  Size _cellSize, ---cell的大小,前面的8*8
             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)

    相关函数可参考:HOG:从理论到OpenCV实践

     setSVMDetector 函数

    (1)作用:设置线性SVM分类器的系数
    (2)函数原型:C++: void gpu::HOGDescriptor::setSVMDetector(const vector<float>& detector
    detect 函数
    (1)作用:用没有多尺度的窗口进行物体检测
    (2)函数原型:
    C++: void gpu::HOGDescriptor::detect(const GpuMat& img
                         vector<Point>& found_locations
                         double hit_threshold=0, 
                         Size win_stride=Size(), 
                         Size padding=Size()
                         )  
    (3)参数注释
    <1>img:源图像。只支持CV_8UC1和CV_8UC4数据类型。
    <2>found_locations:检测出的物体的边缘。
    <3>hit_threshold:特征向量和SVM划分超平面的阀值距离。通常它为0,并应由检测器系数决定。但是,当系数被省略时,可以手动指定它。
    <4>win_stride:窗口步长,必须是块步长的整数倍。
    <5>padding:模拟参数,使得CUP能兼容。目前必须是(0,0)。

    下面是简单调用api进行行人检测:

    #include <opencv2/opencv.hpp>
    #include <opencv2/objdetect.hpp>
    using namespace std;
    using namespace cv;
    
    int main()
    {
        Mat src, dst;
        src = imread("E:\VS2015Opencv\vs2015\project\picture\x1.png", 1);
        if (src.empty())
        {
            printf("can not load the image...
    ");
            return -1;
        }
        dst = src.clone();
        vector<Rect> findrects, findrect;
        HOGDescriptor HOG;
        //SVM分类器
        HOG.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
        //多尺度检测
        HOG.detectMultiScale(src, findrects, 0, Size(4, 4), Size(0, 0), 1.05, 2);
        //若rects有嵌套,则取最外面的矩形存入rect
        for (int i = 0; i < findrects.size(); i++)
        {
            Rect rect = findrects[i];
            int j = 0;
            for (; j < findrects.size(); j++)
                if (j != i && (rect & findrects[j]) == rect)
                    break;
            if (j == findrects.size())
                findrect.push_back(rect);
        }
        //框选出检测结果
        for (int i = 0; i<findrect.size(); i++)
        {
            RNG rng(i);
            Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
            rectangle(dst, findrect[i].tl(), findrect[i].br(), color, 2);
        }
    
        imshow("src", src);
        imshow("dst", dst);
        waitKey();
        return 0;
    }

  • 相关阅读:
    开发中遇到的编码的坑[开发篇]
    linux中ftp的安装过程记录[运维篇]
    在windows如何操控一些屌炸天的linux命令[利刃篇]
    php开发中应该注意的错误开关与常见处理[开发篇]
    微软职位内部推荐-Senior Development Lead
    微软职位内部推荐-Senior SDE
    微软职位内部推荐-Senior Software Development En
    微软职位内部推荐-SDEII
    微软职位内部推荐-Senior SDE
    微软职位内部推荐-Principal Software Developer
  • 原文地址:https://www.cnblogs.com/fcfc940503/p/11348055.html
Copyright © 2020-2023  润新知