opencv行人检测里遇到的setSVMDetector()问题
参考了博客http://blog.csdn.net/carson2005/article/details/7841443 后,自己动手后发现了一些问题,博客里提到的一些问题没有解决
,是关于为什么图像的HOG特征向量debug后是15876的问题。答案是因为原作者的窗口是64*64的,所以维数为9*4*7*7=1764(图像的大小也是64*64,所以图像的特征维数与一个窗口的维数是相同的,compute()里的窗口步进(8,8)也是无效的)。而我的图像时64*128大小的,我把窗口也换成
64*128,所以维数就是3780了,与setSVMDetector默认的getDefaultPeopleDetector大小一样(大概小于getDefaultPeopleDetector()大小为(3781*1))的vector传到setSVMDetector()里都没关系吧,不会出现断言错误。
上代码:
/*
* =====================================================================================
*
* Filename: people_detector.cpp
* Environment:
* Description: 行人检测程序,程序里窗口大小和图片大小一样大,都是64*128
*
*
*
* Version: 1.0
* Created: 2013/10/20 10:45:02
* Author: yuliyang
I*
* Mail: wzyuliyang911@gmail.com
* Blog: http://www.cnblogs.com/yuliyang
*
* =====================================================================================
*/ #include "opencv2/opencv.hpp"
#include "windows.h"
#include "fstream"
#include <iostream>
using namespace std;
using namespace cv;
class Mysvm: public CvSVM
{
public:
int get_alpha_count()
{
return this->sv_total;
} int get_sv_dim()
{
return this->var_all;
} int get_sv_count()
{
return this->decision_func->sv_count;
} double* get_alpha()
{
return this->decision_func->alpha;
} float** get_sv()
{
return this->sv;
} float get_rho()
{
return this->decision_func->rho;
}
}; int my_train()
{ /*-----------------------------------------------------------------------------
* e:/pedestrianDetect-peopleFlow.txt是用来保存所有样本的特征,大小为样本数*3780(每个样本的特征数)
*
*
*
*
*-----------------------------------------------------------------------------*/
char classifierSavePath[] = "e:/pedestrianDetect-peopleFlow.txt";
string buf;
vector<string> pos_img_path;
vector<string> neg_img_path;
ifstream svm_pos_data("pos.txt"); /* 批处理程序生成 */
ifstream svm_neg_data("neg.txt"); /* 批处理生成 */
while( svm_pos_data )//将训练样本文件依次读取进来
{
if( getline( svm_pos_data, buf ) )
pos_img_path.push_back( buf ); }
while( svm_neg_data )//将训练样本文件依次读取进来
{
if( getline( svm_neg_data, buf ) )
neg_img_path.push_back( buf ); }
cout<<pos_img_path.size()<<"个正样本"<<endl;
cout<<neg_img_path.size()<<"个负样本"<<endl;
int totalSampleCount=pos_img_path.size()+neg_img_path.size();
CvMat *sampleFeaturesMat = cvCreateMat(totalSampleCount , , CV_32FC1);
//64*128窗口大小的训练样本,该矩阵将是totalSample*3780
//64*64的窗口大小的训练样本,该矩阵将是totalSample*1764
cvSetZero(sampleFeaturesMat);
CvMat *sampleLabelMat = cvCreateMat(totalSampleCount, , CV_32FC1);//样本标识
cvSetZero(sampleLabelMat); cout<<"************************************************************"<<endl;
cout<<"start to training positive samples..."<<endl; for(int i=; i<pos_img_path.size(); i++)
{
cv::Mat img = cv::imread(pos_img_path.at(i)); if( img.data == NULL )
{
cout<<"positive image sample load error: "<<i<<endl;
system("pause");
continue;
} cv::HOGDescriptor hog(cv::Size(,), cv::Size(,), cv::Size(,), cv::Size(,), );
vector<float> featureVec; hog.compute(img, featureVec, cv::Size(,));
unsigned int featureVecSize = featureVec.size(); for (int j=; j<featureVecSize; j++)
{
CV_MAT_ELEM( *sampleFeaturesMat, float, i, j ) = featureVec[j];
}
sampleLabelMat->data.fl[i] = ;
}
cout<<"end of training for positive samples..."<<endl; cout<<"*********************************************************"<<endl;
cout<<"start to train negative samples..."<<endl; for (int i=; i<neg_img_path.size(); i++)
{ cv::Mat img = cv::imread(neg_img_path.at(i));
if(img.data == NULL)
{
cout<<"negative image sample load error: "<<endl;
continue;
} cv::HOGDescriptor hog(cv::Size(,), cv::Size(,), cv::Size(,), cv::Size(,), );
vector<float> featureVec; hog.compute(img,featureVec,cv::Size(,));//计算HOG特征
int featureVecSize = featureVec.size(); for ( int j=; j<featureVecSize; j ++)
{
CV_MAT_ELEM( *sampleFeaturesMat, float, i + pos_img_path.size(), j ) = featureVec[ j ];
} sampleLabelMat->data.fl[ i + pos_img_path.size() ] = -;
} cout<<"end of training for negative samples..."<<endl;
cout<<"********************************************************"<<endl;
cout<<"start to train for SVM classifier..."<<endl; CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, , FLT_EPSILON);
params.C = 0.01; Mysvm svm;
svm.train( sampleFeaturesMat, sampleLabelMat, NULL, NULL, params ); //用SVM线性分类器训练
svm.save(classifierSavePath); cvReleaseMat(&sampleFeaturesMat);
cvReleaseMat(&sampleLabelMat); int supportVectorSize = svm.get_support_vector_count();
cout<<"support vector size of SVM:"<<supportVectorSize<<endl;
cout<<"************************ end of training for SVM ******************"<<endl; CvMat *sv,*alp,*re;//所有样本特征向量
sv = cvCreateMat(supportVectorSize , , CV_32FC1);
alp = cvCreateMat( , supportVectorSize, CV_32FC1);
re = cvCreateMat( , , CV_32FC1);
CvMat *res = cvCreateMat( , , CV_32FC1); cvSetZero(sv);
cvSetZero(re); for(int i=; i<supportVectorSize; i++)
{
memcpy( (float*)(sv->data.fl+i*), svm.get_support_vector(i), *sizeof(float));
} double* alphaArr = svm.get_alpha();
int alphaCount = svm.get_alpha_count(); for(int i=; i<supportVectorSize; i++)
{
alp->data.fl[i] = (float)alphaArr[i];
}
cvMatMul(alp, sv, re); int posCount = ;
for (int i=; i<; i++)
{
re->data.fl[i] *= -;
} /*-----------------------------------------------------------------------------
* e:/hogSVMDetector-peopleFlow.txt文件中保存的是支持向量,共有3781个值,是一个3781*1的列向量
*
*
*-----------------------------------------------------------------------------*/
FILE* fp = fopen("e:/hogSVMDetector-peopleFlow.txt","wb");
if( NULL == fp )
{
return ;
}
for(int i=; i<; i++)
{
fprintf(fp,"%f \n",re->data.fl[i]);
}
float rho = svm.get_rho();
fprintf(fp, "%f", rho);
cout<<"e:/hogSVMDetector.txt 保存完毕"<<endl;//保存HOG能识别的分类器
fclose(fp); return ;
}
void my_detect()
{
CvCapture* cap = cvCreateFileCapture("E:\\test.avi");
if (!cap)
{
cout<<"avi file load error..."<<endl;
system("pause");
exit(-);
} vector<float> x;
ifstream fileIn("e:/hogSVMDetector-peopleFlow.txt", ios::in);
float val = 0.0f;
while(!fileIn.eof())
{
fileIn>>val;
x.push_back(val);
}
fileIn.close(); vector<cv::Rect> found;
cv::HOGDescriptor hog(cv::Size(,), cv::Size(,), cv::Size(,), cv::Size(,), ); /*-----------------------------------------------------------------------------
*
*
* 如果setSVMDetector出现问题的话,可能是这个原因:因为默认hog.getDefaultPeopleDetector()
* 获取的检测器的大小是3781*1的列向量,所以如果生成的e:/hogSVMDetector-peopleFlow.txt里的大小不等的话
* ,读入
* 就会出现错误,可能这个函数考虑了运行的速度问题,所以限制了大小为3781*1
*
* 特别注意:有些童鞋可能生成的特征向量是15876(所以setSVMDetector里的列向量就是15877了与默认的大小不一,assetion就出错了)
* ,只要调整下图像的大小和检测窗口的大小,使生成的特征向量为3780就行了,怎么计算,可以参考
* 网上其他博客
*
*-----------------------------------------------------------------------------*/
hog.setSVMDetector(x); IplImage* img = NULL;
cvNamedWindow("img", );
while(img=cvQueryFrame(cap))
{
hog.detectMultiScale(img, found, , cv::Size(,), cv::Size(,), 1.05, );
if (found.size() > )
{
for (int i=; i<found.size(); i++)
{
CvRect tempRect = cvRect(found[i].x, found[i].y, found[i].width, found[i].height); cvRectangle(img, cvPoint(tempRect.x,tempRect.y),
cvPoint(tempRect.x+tempRect.width,tempRect.y+tempRect.height),CV_RGB(,,), );
}
}
}
cvReleaseCapture(&cap);
} int main(int argc, char** argv){ //my_train();
//my_detect();
vector<float> x;
ifstream fileIn("e:/hogSVMDetector-peopleFlow.txt", ios::in); /* 读入支持向量,没必要读入样本的向量 */
float val = 0.0f;
while(!fileIn.eof())
{
fileIn>>val;
x.push_back(val);
}
fileIn.close(); vector<Rect> found, found_filtered;
cv::HOGDescriptor hog(cv::Size(,), cv::Size(,), cv::Size(,), cv::Size(,), );
hog.setSVMDetector(x); Mat img;
img=imread("1.jpg",);
hog.detectMultiScale(img, found, , cv::Size(,), cv::Size(,), 1.05, );
size_t i, j;
for( i = ; i < found.size(); i++ )
{
Rect r = found[i];
for( j = ; j < found.size(); j++ )
if( j != i && (r & found[j]) == r)
break;
if( j == found.size() )
found_filtered.push_back(r);
}
for( i = ; i < found_filtered.size(); i++ )
{
Rect r = found_filtered[i];
// the HOG detector returns slightly larger rectangles than the real objects.
// so we slightly shrink the rectangles to get a nicer output.
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(img, r.tl(), r.br(), cv::Scalar(,,), );
}
imshow("people detector", img);
waitKey(); /*cvNamedWindow("img", 0);
string testimage="E:\database\picture_resize_pos\resize000r.bmp";
Mat img=cv::imread(testimage);
hog.detectMultiScale(img, found, 0, cv::Size(8,8), cv::Size(32,32), 1.05, 2);
if (found.size() > 0)
{
printf("found!");
}*/ return ; }
运行效果:
正样本1500多个,负样本400多个,所以效果不咋地,只能呵呵了。
再上一张效果图:(ps:运行的太慢了)
opencv行人检测里遇到的setSVMDetector()问题的更多相关文章
- 学习OpenCV——行人检测&人脸检测(总算运行出来了)
之前运行haar特征的adaboost算法人脸检测一直出错,加上今天的HOG&SVM行人检测程序,一直报错. 今天总算发现自己犯了多么白痴的错误——是因为外部依赖项lib文件没有添加完整,想一 ...
- opencv+树莓PI的基于HOG特征的行人检测
树莓PI远程控制摄像头请参考前文:http://www.cnblogs.com/yuliyang/p/3561209.html 参考:http://answers.opencv.org/questio ...
- 【图像处理】使用OpenCV实现人脸和行人检测
OpenCV全称是Open source Computer Vision Library(开放源代码计算机视觉库),是一个用于图像处理.分析.机器视觉方面的开源函数库,提供了很多图像处理的工具和可 ...
- OpenCV中基于HOG特征的行人检测
目前基于机器学习方法的行人检测的主流特征描述子之一是HOG(Histogram of Oriented Gradient, 方向梯度直方图).HOG特征是用于目标检测的特征描述子,它通过计算和统计图像 ...
- OpenCV人形检测Hog
#include "iostream" #include "queue" using namespace std; #include "opencv2 ...
- Hog SVM 车辆 行人检测
HOG SVM 车辆检测 近期需要对卡口车辆的车脸进行检测,首先选用一个常规的检测方法即是hog特征与SVM,Hog特征是由dalal在2005年提出的用于道路中行人检测的方法,并且取的了不错的识别效 ...
- 自己训练SVM分类器进行HOG行人检测
正样本来源是INRIA数据集中的96*160大小的人体图片,使用时上下左右都去掉16个像素,截取中间的64*128大小的人体. 负样本是从不包含人体的图片中随机裁取的,大小同样是64*128(从完全不 ...
- hog行人检测
本文主要介绍下opencv中怎样使用hog算法,因为在opencv中已经集成了hog这个类.其实使用起来是很简单的,从后面的代码就可以看出来.本文参考的资料为opencv自带的sample. 关于op ...
- PCL行人检测
首先我们知道Hog特征结合SVM分类器已经被广泛应用于图像识别中,尤其在行人检测中获得了极大的成功,HOG+SVM进行行人检测的方法是法国研究人员Dalal在2005的CVPR上提出的,而如今虽然有很 ...
随机推荐
- @Override在JDK1.5和JDK1.6中用法区别
@Override 注解在jdk1.5环境下,只能用于对基类(父类)的方法的重写.而不能用于对实现的接口的方法的实现.而在jdk1.6环境下,两者都适用.
- 10 harsh truths that will help you grow
10 harsh truths that will help you grow帮你成长的10个残酷事实In the game of life, if it often seems like you’r ...
- 输出进程相关联的环境变量信息(使用GetEnvironmentStrings取得信息,然后使用StringCchCopyN和StringCchPrintf保证字符串不会越界)
void DumpEnvironmentStrings() { #define MAX_ENVIRONMENT_NAME_LENGTH (128) #define MAX_ENVIRONMEN ...
- Android 自定义Android带图片和文字的ImageButton
经过分析,上述按钮效果实际上就是一个布局,一个最简单不过的垂直线性布局,上部分是一个ImageView,下部分是一个TextView,这个布局可点击.可设置监听. 我们首先要编写自己的ImageBut ...
- 即时通信Spark安装和配置
spark:Cross-platform real-time collaboration client optimized for business and organizations.Spark i ...
- android logcat里面AndroidRuntime FATAL EXCEPTION: main这个是什么问题啊。
android logcat里面AndroidRuntime FATAL EXCEPTION: main这个是什么问题啊. http://zhidao.baidu.com/link?url=mUI11 ...
- struct dev_t
device number(dev_t) linux driver 2009-08-21 10:08:03 阅读26 评论0 字号:大中小 dev_t description: the dev ...
- Oracle过程包加密
Oracle加绕功能可以将PL/SQL代码实现部分隐藏,如存储过程.函数.包体等均可使用加绕功能,下面以一个存储过程实现部分加绕来展示Oracle加绕功能的使用. 加绕方法一: 1.编写如下存储过程 ...
- Failed to initialize monitor Thread: Unable to establish loopback connection解决方法
原因一: android中出现该异常的原因,是pid产生了冲突,将服务中的windows Firewall 服务停用就行了 原因二: http://stackoverflow.com/question ...
- Qt之QTableView添加复选框(QAbstractTableModel)
简述 使用QTableView,经常会遇到复选框,要实现一个好的复选框,除了常规的功能外,还应注意以下几点: 三态:不选/半选/全选 自定义风格(样式) 下面我们介绍一下常见的实现方式: 编辑委托. ...