hog+svm+检测人(代替默认的参数)
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
//#include <opencv2/gpu/gpu.hpp>
#include <fstream>
#include <iomanip>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#define FEATURE_DIM 3780
using namespace std;
using namespace cv;
class MySVM : public CvSVM
{
public:
//获得SVM的决策函数中的alpha数组
double * get_alpha_vector()
{
return this->decision_func->alpha;
}
//获得SVM的决策函数中的rho参数,即偏移量
float get_rho()
{
return this->decision_func->rho;
}
};
int main()
{
#if 0
Mat image;
image = imread("D:\\dataset\\temp\\6.png");
HOGDescriptor hog;
vector<float> v_feature;
hog.compute(image, v_feature, cv::Size(8, 8));
//hog.compute(image, v_feature, cv::Size(16, 16));
int featureVecSize = v_feature.size();
cout << "****************************************haha****************" << endl;
cout << featureVecSize << endl;
#else
//***************************************************************************************************
// 初始化
//***************************************************************************************************
//char positivePath[256] = "D:\\dataset\\INRIAPerson\\Train\\pos\\"; //改路径
//char negativePath[256] = "D:\\dataset\\INRIAPerson\\Train\\neg\\";
//char testPath[256] = "D:\\dataset\\INRIAPerson\\Test\\pos\\";
char positivePath[256] = "D:\\dataset\\INRIAPerson\\train_64x128_H96\\pos\\";
char negativePath[256] = "D:\\dataset\\INRIAPerson\\train_64x128_H96\\neg\\";
//char testPath[256] = "D:\\dataset\\INRIAPerson\\70X134H96\\Test\\pos\\";
char testPath[256] = "D:\\dataset\\INRIAPerson\\test_64x128_H96\\pos\\";
//char testPath[256] = "D:\\dataset\\INRIAPerson\\test_64x128_H96\\neg\\";
char classifierSavePath[256] = "D:\\dataset\\INRIAPerson\\myResult";
int positiveSampleCount = 614; //改数据
int negativeSampleCount = 1218;
//int positiveSampleCount = 100;
//int negativeSampleCount = 100;
int totalSampleCount = positiveSampleCount + negativeSampleCount;
int testSampleCount = 1126;
//int testSampleCount = 100;
CvMat *sampleFeaturesMat = cvCreateMat(totalSampleCount, FEATURE_DIM, CV_32FC1); //改向量维数
cvSetZero(sampleFeaturesMat);
CvMat *sampleLabelMat = cvCreateMat(totalSampleCount, 1, CV_32FC1);
cvSetZero(sampleLabelMat);
//CvMat *testFeaturesMat = cvCreateMat(testSampleCount, FEATURE_DIM, CV_32FC1); //参数1764? 正288,负453
CvMat *testFeaturesMat = cvCreateMat(1, FEATURE_DIM, CV_32FC1); //参数1764? 正288,负453
cvSetZero(testFeaturesMat);
//CvMat *testLabelMat = cvCreateMat(testSampleCount, 1, CV_32FC1);//样本标识
//cvSetZero(testLabelMat);
float testLabelMat[288] = { 0.0 };
//Mat sampleFeaturesMat();
HOGDescriptor hog(Size(64, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9);//HOG检测器,用来计算HOG描述子的
vector<float> v_feature;
//***************************************************************************************************
// 正例的特征
//***************************************************************************************************
//positive文件读入
//ifstream fin(positivePath, ios::in);
//if (!fin)
//{
// cout << "positivePath can not open the file!" << endl;
// return -1;
//}
char positiveImage[256];
string path;
string s_positiveImage;
for (int i = 0; i < positiveSampleCount; i++)
{
//图片名修改
memset(positiveImage, '\0', sizeof(positiveImage));
sprintf(positiveImage, "%d.png", i + 1); //要改成.jpg吗
s_positiveImage = positiveImage;
path = positivePath + s_positiveImage;
Mat image = imread(path);
if (image.data == NULL)
{
cout << "positive image sample load error: " << i << " " << path << endl;
system("pause");
continue;
}
//hog特征提取
//gpu::HOGDescriptor hog(Size(64, 64), Size(16, 16), Size(8, 8), Size(8, 8), 9); //貌似还有一些参数,重载了?
//HOGDescriptor hog(Size(64, 64), Size(16, 16), Size(8, 8), Size(8, 8), 9);
//HOGDescriptor hog;
// vector<float> v_feature;
image = image(Rect(16, 16, 64, 128));
hog.compute(image, v_feature, cv::Size(8, 8));
//hog.compute(image, v_feature, cv::Size(16, 16));
int featureVecSize = v_feature.size();
//cout << "****************************************haha****************" << endl;
//cout << featureVecSize<<endl;
//return 0;
for (int j = 0; j<featureVecSize; j++)
{
//sampleFeaturesMat[i][j] = v_feature[j];
CV_MAT_ELEM(*sampleFeaturesMat, float, i, j) = v_feature[j]; //CV_MAT_ELEM什么意思
}
sampleLabelMat->data.fl[i] = 1; //.fl[]是什么
cout << "positive" << i + 1 << "is running..." << endl;
}
//fclose(fin);
//***************************************************************************************************
// 负例的特征
//***************************************************************************************************
//negative文件读入
//ifstream fin(negativePath, ios::in);
//if (!fin)
//{
// cout << "can not open the file!" << endl;
// return -1;
//}
char negativeImage[256] = ""; //初始化吗
string s_negativeImage;
for (int i = 0; i < negativeSampleCount; i++)
{
//图片名修改
//hog特征提取
memset(negativeImage, '\0', sizeof(negativeImage));
sprintf(negativeImage, "%d.png", i + 1); //要改成.jpg吗
s_negativeImage = negativeImage;
path = negativePath + s_negativeImage;
//cout << "********************************************************"<<endl;
//cout << path<<endl;
Mat image = imread(path);
if (image.data == NULL)
{
cout << "positive image sample load error: " << i << " " << path << endl;
system("pause");
continue;
}
//hog特征提取
//gpu::HOGDescriptor hog(Size(64, 64), Size(16, 16), Size(8, 8), Size(8, 8), 9); //貌似还有一些参数,重载了?
//HOGDescriptor hog(Size(64, 64), Size(16, 16), Size(8, 8), Size(8, 8), 9);
//HOGDescriptor hog;
//vector<float> v_feature;
image = image(Rect(16, 16, 64, 128));
hog.compute(image, v_feature, cv::Size(8, 8));
int featureVecSize = v_feature.size();
//cout << "***************************lalala*****************************" << endl;
//cout << featureVecSize;
for (int j = 0; j<featureVecSize; j++)
{
CV_MAT_ELEM(*sampleFeaturesMat, float, positiveSampleCount + i, j) = v_feature[j]; //CV_MAT_ELEM什么意思
}
sampleLabelMat->data.fl[positiveSampleCount + i] = 0; //.fl[]是什么
cout << "negative" << i + 1 << "is running..." << endl;
}
//**********************************************************************************************
// Linear SVM训练
//**********************************************************************************************
//设置参数
CvSVMParams params;
params.svm_type = SVM::C_SVC;
params.C = 0.01;
params.kernel_type = SVM::LINEAR;
//params.term_crit = TermCriteria(CV_TERMCRIT_ITER, (int)1e7, 1e-6);
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, FLT_EPSILON);
//训练
cout << "Starting training process" << endl;
//CvSVM svm;
MySVM svm;
svm.train(sampleFeaturesMat, sampleLabelMat, Mat(), Mat(), params);
cout << "Finished training process" << endl;
//**********************************************************************************************
// 结果保存
//**********************************************************************************************
//classifierSavePath文件读入
//ifstream fin(classifierSavePath, ios::in);
//if (!fin)
//{
// cout << "positivePath can not open the file!" << endl;
// return -1;
//}
//svm.save(classifierSavePath);
//cvReleaseMat(&sampleFeaturesMat);
//cvReleaseMat(&sampleLabelMat);
//cout << "has saved succeeded! " << endl;
//**********************************************************************************************
// 测试
//**********************************************************************************************
//test文件读入
//ifstream fin(testPath, ios::in);
//if (!fin)
//{
// cout << "can not open the file!" << endl;
// return -1;
//}
char testImage[256] = ""; //初始化吗
string s_testImage;
for (int i = 0; i < testSampleCount; i++)
{
//图片名修改
//hog特征提取
memset(testImage, '\0', sizeof(testImage));
sprintf(testImage, "%d.png", i + 1); //要改成.jpg吗
s_testImage = testImage;
path = testPath + s_testImage;
Mat image = imread(path);
if (image.data == NULL)
{
cout << "positive image sample load error: " << i << " " << path << endl;
system("pause");
continue;
}
//hog特征提取
//gpu::HOGDescriptor hog(Size(64, 64), Size(16, 16), Size(8, 8), Size(8, 8), 9); //貌似还有一些参数,重载了?
//HOGDescriptor hog(Size(64, 64), Size(16, 16), Size(8, 8), Size(8, 8), 9);
//HOGDescriptor hog;
//vector<float> v_feature;
image = image(Rect(16, 16, 64, 128));
hog.compute(image, v_feature, cv::Size(8, 8));
int featureVecSize = v_feature.size();
//cout << "***************************lalala*****************************" << endl;
//cout << featureVecSize << endl;
for (int j = 0; j<featureVecSize; j++)
{
//CV_MAT_ELEM(*testFeaturesMat, float, i, j) = v_feature[j]; //CV_MAT_ELEM什么意思
CV_MAT_ELEM(*testFeaturesMat, float, 0, j) = v_feature[j];
}
float response = svm.predict(testFeaturesMat);
//testLabelMat->data.fl[i] = response; //.fl[]是什么
testLabelMat[i] = response;
}
float right = 0;
for (int i = 0; i < testSampleCount; i++)
{
//if (testLabelMat->data.fl[i] == 1)
if (testLabelMat[i] == 1)
{
right++;
}
}
float radio = right / testSampleCount;
cout << "the radio of the train is:" << radio << endl;
/*************************************************************************************************
线性SVM训练完成后得到的XML文件里面,有一个数组,叫做support vector,还有一个数组,叫做alpha,有一个浮点数,叫做rho;
将alpha矩阵同support vector相乘,注意,alpha*supportVector,将得到一个列向量。之后,再该列向量的最后添加一个元素rho。
如此,变得到了一个分类器,利用该分类器,直接替换opencv中行人检测默认的那个分类器(cv::HOGDescriptor::setSVMDetector()),
就可以利用你的训练样本训练出来的分类器进行行人检测了。
***************************************************************************************************/
int DescriptorDim = svm.get_var_count();//特征向量的维数,即HOG描述子的维数
int supportVectorNum = svm.get_support_vector_count();//支持向量的个数
cout << "支持向量个数:" << supportVectorNum << endl;
Mat alphaMat = Mat::zeros(1, supportVectorNum, CV_32FC1);//alpha向量,长度等于支持向量个数
Mat supportVectorMat = Mat::zeros(supportVectorNum, DescriptorDim, CV_32FC1);//支持向量矩阵
Mat resultMat = Mat::zeros(1, DescriptorDim, CV_32FC1);//alpha向量乘以支持向量矩阵的结果
//将支持向量的数据复制到supportVectorMat矩阵中
for (int i = 0; i<supportVectorNum; i++)
{
const float * pSVData = svm.get_support_vector(i);//返回第i个支持向量的数据指针
for (int j = 0; j<DescriptorDim; j++)
{
//cout<<pData[j]<<" ";
supportVectorMat.at<float>(i, j) = pSVData[j];
}
}
//将alpha向量的数据复制到alphaMat中
double * pAlphaData = svm.get_alpha_vector();//返回SVM的决策函数中的alpha向量
for (int i = 0; i<supportVectorNum; i++)
{
alphaMat.at<float>(0, i) = pAlphaData[i];
}
//计算-(alphaMat * supportVectorMat),结果放到resultMat中
//gemm(alphaMat, supportVectorMat, -1, 0, 1, resultMat);//不知道为什么加负号?
resultMat = -1 * alphaMat * supportVectorMat;
//得到最终的setSVMDetector(const vector<float>& detector)参数中可用的检测子
vector<float> myDetector;
//将resultMat中的数据复制到数组myDetector中
for (int i = 0; i<DescriptorDim; i++)
{
myDetector.push_back(resultMat.at<float>(0, i));
}
//最后添加偏移量rho,得到检测子
myDetector.push_back(svm.get_rho());
cout << "特征向量维数:" << svm.get_var_count()<< endl;
cout << "检测子维数:" << myDetector.size() << endl;
//设置HOGDescriptor的检测子
//cout << "默认检测子维数" << hog.getDefaultPeopleDetector().size()<<endl;
//hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
cout<<"特征描述子:"<<hog.getDescriptorSize()<<endl;
cout << "描述子维数:" << v_feature.size() << endl;
hog.setSVMDetector(myDetector); //#############################
cout << "debug:" << endl;
//保存检测子参数到文件
ofstream fout("HOGDetectorForOpenCV.txt");
for (int i = 0; i<myDetector.size(); i++)
{
fout << myDetector[i] << endl;
}
/**************读入图片进行HOG行人检测******************/
//Mat src = imread("00000.jpg");
//Mat src = imread("2007_000423.jpg");
Mat src = imread("D:\\dataset\\temp\\1.jpg");
vector<Rect> found, found_filtered;//矩形框数组
cout << "进行多尺度HOG人体检测" << endl;
hog.detectMultiScale(src, found, 0, Size(8, 8), Size(32, 32), 1.05, 2);//对图片进行多尺度行人检测
cout << "找到的矩形框个数:" << found.size() << endl;
//找出所有没有嵌套的矩形框r,并放入found_filtered中,如果有嵌套的话,则取外面最大的那个矩形框放入found_filtered中
for (int i = 0; i < found.size(); i++)
{
Rect r = found[i];
int j = 0;
for (; j < found.size(); j++)
if (j != i && (r & found[j]) == r)
break;
if (j == found.size())
found_filtered.push_back(r);
}
//画矩形框,因为hog检测出的矩形框比实际人体框要稍微大些,所以这里需要做一些调整
for (int i = 0; i<found_filtered.size(); i++)
{
Rect r = found_filtered[i];
r.x += cvRound(r.width*0.1);
r.width = cvRound(r.width*0.8);
r.y += cvRound(r.height*0.07);
r.height = cvRound(r.height*0.8);
rectangle(src, r.tl(), r.br(), Scalar(0, 255, 0), 3);
}
imwrite("ImgProcessed.jpg", src);
namedWindow("src", 0);
imshow("src", src);
waitKey();//注意:imshow之后必须加waitKey,否则无法显示图像
#endif
return 0;
}
hog+svm+检测人(代替默认的参数)的更多相关文章
- python opencv3 检测人
git:https://github.com/linyi0604/Computer-Vision # coding:utf-8 import cv2 # 检测i方框 包含o方框 def is_insi ...
- 第十八节、基于传统图像处理的目标检测与识别(HOG+SVM附代码)
其实在深度学习中我们已经介绍了目标检测和目标识别的概念.为了照顾一些没有学过深度学习的童鞋,这里我重新说明一次:目标检测是用来确定图像上某个区域是否有我们要识别的对象,目标识别是用来判断图片上这个对象 ...
- 自己训练SVM分类器进行HOG行人检测
正样本来源是INRIA数据集中的96*160大小的人体图片,使用时上下左右都去掉16个像素,截取中间的64*128大小的人体. 负样本是从不包含人体的图片中随机裁取的,大小同样是64*128(从完全不 ...
- HoG SVM 目标检测分析
前一段时间开始了解HoG跟SVM行人识别,看了很多包括Dalal得前辈的文章及经验分享,对HoG理论有了些初步的认识. HoG 的全称是 Histogram of Oriented Gradient, ...
- Hog SVM 车辆 行人检测
HOG SVM 车辆检测 近期需要对卡口车辆的车脸进行检测,首先选用一个常规的检测方法即是hog特征与SVM,Hog特征是由dalal在2005年提出的用于道路中行人检测的方法,并且取的了不错的识别效 ...
- 利用HOG+SVM实现行人检测
利用HOG+SVM实现行人检测 很久以前做的行人检测,现在稍加温习,上传记录一下. 首先解析视频,提取视频的每一帧形成图片存到磁盘.代码如下 import os import cv2 videos_s ...
- 【目标检测】基于传统算法的目标检测方法总结概述 Viola-Jones | HOG+SVM | DPM | NMS
"目标检测"是当前计算机视觉和机器学习领域的研究热点.从Viola-Jones Detector.DPM等冷兵器时代的智慧到当今RCNN.YOLO等深度学习土壤孕育下的GPU暴力美 ...
- HOG + SVM(行人检测, opencv实现)
HOG+SVM流程 1.提取HOG特征 灰度化 + Gamma变换(进行根号求解) 计算梯度map(计算梯度) 图像划分成小的cell,统计每个cell梯度直方图 多个cell组成一个block, 特 ...
- hog行人检测
本文主要介绍下opencv中怎样使用hog算法,因为在opencv中已经集成了hog这个类.其实使用起来是很简单的,从后面的代码就可以看出来.本文参考的资料为opencv自带的sample. 关于op ...
随机推荐
- 卡内基梅隆大学软件工程研究所先后制定用于评价软件系统成熟度的模型CMM和CMMI
SEI(美国卡内基梅隆大学软件工程研究所(Software Engineering Institute, SEI))开发的CMM模型有: 用于软件的(SW-CMM;SW代表'software即软件') ...
- Ubuntu 添加,删除ppa
PPA,英文全称为 Personal Package Archives,即个人软件包档案.是 Ubuntu Launchpad 网站提供的一项源服务,允许个人用户上传软件源代码,通过 Launchpa ...
- Qt532_字符编码转换
1.测试代码: // http://blog.csdn.net/changsheng230/article/details/6588447 QString str = QString::fromLoc ...
- 《剑指offer》第十三题(机器人的运动范围)
// 面试题:机器人的运动范围 // 题目:地上有一个m行n列的方格.一个机器人从坐标(0, 0)的格子开始移动,它 // 每一次可以向左.右.上.下移动一格,但不能进入行坐标和列坐标的数位之和 // ...
- React生命周期钩子
最近的工作都很忙,所以很少完整的时间可以用来总结和回顾知识点,今天就趁着是周末,我准备在这里复习和回顾一下React的基础.工作中主要用的vue比较多,在工作中使用React也已经是一年前了,当时用的 ...
- smarty课程---smarty3的安装和使用
smarty课程---smarty3的安装和使用 一.总结 一句话总结:smarty 是什么,就不多说了,用过php,接触过php的人都对smarty 再熟悉不过了.它是一个很强大的代码分离软件,作为 ...
- Hibernate实例二
Hibernate实例二 一.测试openSession方法和getCurrentSession方法 hebernate中可以通过上述两种方法获取session对象以对数据库进行操作,下面的代码以及注 ...
- ubuntu , 安装包的具体文件的查看方法
To see all the files the package installed onto your system, do this: dpkg-query -L <package_name ...
- Java数据类型转换(自动转换和强制转换)
数据类型的转换,分为自动转换和强制转换.自动转换是程序在执行过程中“悄然”进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换;强制类型转换则必须在代码中声明,转换顺序不受限制. 自 ...
- php-------代码加密的几种方法
代码加密,也是保护网站安全的一种方法,以下我们来介绍一下如何通过PHP的自定义函数来加密我们的PHP代码. 方法一: <?php function encode_file_contents($f ...