当前位置:网站首页>【opencv】train&test HOG+SVM
【opencv】train&test HOG+SVM
2022-07-02 00:16:00 【Ten year dream laboratory】
#include <iostream>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/ml/ml.hpp>
#include <cxcore.h>
#include <cv.h>
using namespace std;
using namespace cv;
#define PosSamNO 46 // Number of positive samples
#define NegSamNO 72 // Number of negative samples
#define TRAIN true // Training ,true It means retraining ,false Means read xml In the document SVM Model
#define CENTRAL_CROP true //true: During training , Yes 96*160 Of INRIA Cut out the middle of the sample image 64*128 The size of the human body
//HardExample: Number of negative samples . If HardExampleNO Greater than 0, After processing the initial negative sample set , To continue processing HardExample Negative sample set .
// Don't use HardExample Must be set to 0, Because this value is used when initializing the dimensions of eigenvector matrix and eigenclass matrix
#define HardExampleNO 0
// Inherited from CvSVM Class , Because it generates setSVMDetector() When detecting sub parameters used in , You need to use trained SVM Of decision_func Parameters ,
// But by looking at CvSVM Source code is known decision_func Parameter is protected Type variable , Cannot directly access , Can only be accessed through functions after inheritance
class MySVM : public CvSVM
{
public:
// get SVM In the decision function of alpha Array
double * get_alpha_vector()
{
return this->decision_func->alpha;
}
// get SVM In the decision function of rho Parameters , The offset
float get_rho()
{
return this->decision_func->rho;
}
};
int main()
{
// Detection window (64,128), Block size (16,16), Block step size (8,8),cell Size (8,8), Histogram bin Number 9
/* First of all */HOGDescriptor hog(Size(64,64),Size(16,16),Size(8,8),Size(8,8),9);//HOG detector , To calculate HOG The description of
int DescriptorDim;//HOG The dimension of the descriptor , By picture size 、 Detection window size 、 Block size 、 Histograms in cell units bin The number determines
MySVM svm;//SVM classifier
// if TRAIN by true, Retraining the classifier
if(TRAIN)
{
string ImgName;// Picture name ( Absolute path )
ifstream finPos("/Users/ymy/Desktop/SVM2/SVM2/pos/pos.txt");// The file name list of the sample image
ifstream finNeg("/Users/ymy/Desktop/SVM2/SVM2/neg/neg.txt");// List of file names for negative sample images
Mat sampleFeatureMat;// A matrix composed of eigenvectors of all training samples , The number of rows is equal to the number of all samples , The number of columns is equal to HOG The dimension of descriptors
Mat sampleLabelMat;// Class vectors of training samples , The number of rows is equal to the number of all samples , The number of columns is equal to 1;1 It means that someone ,-1 No one
// Read the positive sample image in turn , Generate HOG Narrator
for(int num=0; num<PosSamNO && getline(finPos,ImgName); num++)
{
cout<<" Handle :"<<ImgName<<endl;
Mat src = imread(ImgName);// Read the picture
/* The second place */resize(src,src,Size(64,64));
//resize(src,src,Size(64,64));
vector<float> descriptors;//HOG The descriptor vector
//cout<< grad.cols;
hog.compute(src,descriptors,Size(8,8));// Calculation HOG Narrator , Detection window moving step size (8,8)
//cout<<" The dimension of descriptors :"<<descriptors.size()<<endl;
// When processing the first sample, initialize the eigenvector matrix and category matrix , Because only when we know the dimension of the eigenvector can we initialize the eigenvector matrix
if( 0 == num )
{
DescriptorDim = descriptors.size();//HOG The dimension of the descriptor
// Initialize the matrix composed of eigenvectors of all training samples , The number of rows is equal to the number of all samples , The number of columns is equal to HOG The dimension of descriptors sampleFeatureMat
sampleFeatureMat = Mat::zeros(PosSamNO+NegSamNO+HardExampleNO, DescriptorDim, CV_32FC1);
// Initialize the class vector of the training sample , The number of rows is equal to the number of all samples , The number of columns is equal to 1;1 It means that someone ,0 No one
sampleLabelMat = Mat::zeros(PosSamNO+NegSamNO+HardExampleNO, 1, CV_32FC1);
}
// The calculated HOG The descriptor is copied to the sample feature matrix sampleFeatureMat
for(int i=0; i<DescriptorDim; i++)
sampleFeatureMat.at<float>(num,i) = descriptors[i];// The first num The second of the eigenvectors of a sample i Elements
sampleLabelMat.at<float>(num,0) = 1;// The positive sample category is 1, someone
}
// Read the negative sample image in turn , Generate HOG Narrator
for(int num=0; num<NegSamNO && getline(finNeg,ImgName); num++)
{
cout<<" Handle :"<<ImgName<<endl;
//cout<<ImgName<<endl;
//waitKey();
Mat src = imread(ImgName);// Read the picture
/* The third place */resize(src,src,Size(128,128));
vector<float> descriptors;//HOG The descriptor vector
hog.compute(src,descriptors,Size(8,8));// Calculation HOG Narrator , Detection window moving step size (8,8)
//cout<<" The dimension of descriptors :"<<descriptors.size()<<endl;
// The calculated HOG The descriptor is copied to the sample feature matrix sampleFeatureMat
for(int i=0; i<DescriptorDim; i++)
sampleFeatureMat.at<float>(num+PosSamNO,i) = descriptors[i];// The first PosSamNO+num The second of the eigenvectors of a sample i Elements
sampleLabelMat.at<float>(num+PosSamNO,0) = -1;// The negative sample category is -1, Unmanned
}
// Handle HardExample Negative sample
if(HardExampleNO > 0)
{
ifstream finHardExample("HardExample_2400PosINRIA_12000NegList.txt");//HardExample Negative sample file name list
// Read... In turn HardExample Negative sample image , Generate HOG Narrator
for(int num=0; num<HardExampleNO && getline(finHardExample,ImgName); num++)
{
cout<<" Handle :"<<ImgName<<endl;
ImgName = "D:\\DataSet\\HardExample_2400PosINRIA_12000Neg\\" + ImgName;// add HardExample Pathnames of negative samples
Mat src = imread(ImgName);// Read the picture
//resize(src,img,Size(64,128));
vector<float> descriptors;//HOG The descriptor vector
hog.compute(src,descriptors,Size(8,8));// Calculation HOG Narrator , Detection window moving step size (8,8)
//cout<<" The dimension of descriptors :"<<descriptors.size()<<endl;
// The calculated HOG The descriptor is copied to the sample feature matrix sampleFeatureMat
for(int i=0; i<DescriptorDim; i++)
sampleFeatureMat.at<float>(num+PosSamNO+NegSamNO,i) = descriptors[i];// The first PosSamNO+num The second of the eigenvectors of a sample i Elements
sampleLabelMat.at<float>(num+PosSamNO+NegSamNO,0) = -1;// The negative sample category is -1, Unmanned
}
}
// Training SVM classifier
// Iteration termination condition , When the iteration is full 1000 Time or error is less than FLT_EPSILON Stop iterating
CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 1000, FLT_EPSILON);
//SVM Parameters :SVM The type is C_SVC; Linear kernel function ; Relaxation factor C=0.01
CvSVMParams param(CvSVM::C_SVC, CvSVM::LINEAR, 0, 1, 0, 0.01, 0, 0, 0, criteria);
cout<<" Start training SVM classifier "<<endl;
svm.train(sampleFeatureMat, sampleLabelMat, Mat(), Mat(), param);// Training classifier
cout<<" Training done "<<endl;
svm.save("/Users/ymy/Desktop/SVM_HOG.xml");// Will be trained SVM Save model as xml file
}
else // if TRAIN by false, from XML File read trained classifier
{
svm.load("/Users/ymy/Desktop/SVM_HOG.xml");// from XML File read trained SVM Model
}
/*************************************************************************************************
linear SVM After training, I got XML In the document , I have an array , be called support vector, There is also an array , be called alpha, There's a floating-point number , be called rho;
take alpha Matrix identical support vector Multiply , Be careful ,alpha*supportVector, You'll get a column vector . after , Add an element at the end of the column vector rho.
such , It becomes a classifier , Using this classifier , Direct replacement opencv The default classifier for Chinese people detection (cv::HOGDescriptor::setSVMDetector()),
You can use the classifier trained by your training samples to detect pedestrians .
***************************************************************************************************/
DescriptorDim = svm.get_var_count();// The dimension of the eigenvector , namely HOG The dimension of the descriptor
int supportVectorNum = svm.get_support_vector_count();// The number of support vectors
cout<<" The number of support vectors :"<<supportVectorNum<<endl;
Mat alphaMat = Mat::zeros(1, supportVectorNum, CV_32FC1);//alpha vector , The length is equal to the number of support vectors
Mat supportVectorMat = Mat::zeros(supportVectorNum, DescriptorDim, CV_32FC1);// Support vector matrix
Mat resultMat = Mat::zeros(1, DescriptorDim, CV_32FC1);//alpha The result of multiplying the vector by the support vector matrix
// Copy the support vector data to supportVectorMat Matrix
for(int i=0; i<supportVectorNum; i++)
{
const float * pSVData = svm.get_support_vector(i);// Back to page i A data pointer to a support vector
for(int j=0; j<DescriptorDim; j++)
{
//cout<<pData[j]<<" ";
supportVectorMat.at<float>(i,j) = pSVData[j];
}
}
// take alpha The vector data is copied to alphaMat in
double * pAlphaData = svm.get_alpha_vector();// return SVM In the decision function of alpha vector
for(int i=0; i<supportVectorNum; i++)
{
alphaMat.at<float>(0,i) = pAlphaData[i];
}
// Calculation -(alphaMat * supportVectorMat), The result is put in resultMat in
//gemm(alphaMat, supportVectorMat, -1, 0, 1, resultMat);// I don't know why to add a minus sign ?
resultMat = -1 * alphaMat * supportVectorMat;
// To get the final setSVMDetector(const vector<float>& detector) The detectors available in the parameter
vector<float> myDetector;
// take resultMat Copy the data in to the array myDetector in
for(int i=0; i<DescriptorDim; i++)
{
myDetector.push_back(resultMat.at<float>(0,i));
}
// Finally, add the offset rho, Get the detector
myDetector.push_back(svm.get_rho());
cout<<" Check the sub dimension :"<<myDetector.size()<<endl;
//waitKey();
// Set up HOGDescriptor It's a good detector
/* The first around */HOGDescriptor myHOG(Size(64,64),Size(16,16),Size(8,8),Size(8,8),9);
cout<<myHOG.getDescriptorSize()<<endl;
//waitKey();
myHOG.setSVMDetector(myDetector);
//myHOG.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
// Save the detection sub parameters to a file
ofstream fout("HOGDetectorForOpenCV.txt");
for(int i=0; i<myDetector.size(); i++)
{
fout<<myDetector[i]<<endl;
}
/************** Read in video for HOG Pedestrian detection ******************/
VideoCapture cap("/Users/ymy/Downloads/IMG_0249.MOV");// Car front detection
Mat src;
for(;;)
{
cap >> src;
cap >> src;
cap >> src;
cap >> src;
if( !src.empty() )
{
resize(src,src,Size(200,372));
vector<Rect> found, found_filtered;// Rectangle array
//cout<<" Multi scale HOG Human detection "<<endl;
myHOG.detectMultiScale(src, found, 0, Size(8,8), Size(32,32), 1.05, 2);// Multi scale pedestrian detection on images
cout<<" Number of rectangles found :"<<found.size()<<endl;
// Find all rectangles that are not nested r, And put in found_filtered in , If there's nesting , Take the largest rectangle outside and put it in found_filtered in
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);
}
// Draw a rectangle , because hog The detected rectangle is slightly larger than the actual human frame , So we need to make some adjustments here
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);
}
imshow("src",src);
}
else
{ printf(" --(!) No captured frame -- Break!"); break; }
int c = waitKey(1);
if( (char)c == 'c' ) { break; }
}
/****************************************************/
/************** Read in the picture and HOG Pedestrian detection ******************
//Mat src = imread("00000.jpg");
//Mat src = imread("2007_000423.jpg");/Users/ymy/Downloads/2012-03-07-08-48-19.jpg
Mat src = imread("/Users/ymy/Desktop/SVM2/SVM2/pos/9.png");//"/Users/ymy/Pictures/FN2V63AD2J.com.tencent.ScreenCapture2/[email protected]");///Users/ymy/Desktop/test.jpg");
//resize(src,src,Size(200,372));
resize(src,src,Size(100,100));
vector<Rect> found, found_filtered;// Rectangle array
//cout<<" Multi scale HOG Human detection "<<endl;
myHOG.detectMultiScale(src, found, 0, Size(8,8), Size(32,32), 1.05, 2);// Multi scale pedestrian detection on images
cout<<" Number of rectangles found :"<<found.size()<<endl;
// Find all rectangles that are not nested r, And put in found_filtered in , If there's nesting , Take the largest rectangle outside and put it in found_filtered in
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);
}
// Draw a rectangle , because hog The detected rectangle is slightly larger than the actual human frame , So we need to make some adjustments here
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("/Users/ymy/Desktop/ImgProcessed.jpg",src);
imshow("src",src);
waitKey();// Be careful :imshow After that, we have to add waitKey, Otherwise, the image cannot be displayed
/******************************************************************************/
/****************** Batch processing negative samples *************************************************
string ImgN,ImgN1;
ifstream finNeg("/Users/ymy/Desktop/SVM2/SVM2/neg/neg.txt");// List of file names for negative sample images
ifstream finNeg1("/Users/ymy/Desktop/SVM2/SVM2/neg/neg1.txt");
getline(finNeg,ImgN);
for(int i=1;i<491;i++)
{
cout<<" The first "<<i<<" picture "<<endl;
Mat src = imread(ImgN);
getline(finNeg,ImgN);
//resize(src,src,Size(200,200));
vector<Rect> found, found_filtered;// Rectangle array
//cout<<" Multi scale HOG Human detection "<<endl;
myHOG.detectMultiScale(src, found, 0, Size(8,8), Size(32,32), 1.05, 2);// Multi scale pedestrian detection on images
cout<<" Number of rectangles found :"<<found.size()<<endl;
// Find all rectangles that are not nested r, And put in found_filtered in , If there's nesting , Take the largest rectangle outside and put it in found_filtered in
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);
}
// Draw a rectangle , because hog The detected rectangle is slightly larger than the actual human frame , So we need to make some adjustments here
for(int i=0; i<found_filtered.size(); i++)
{
getline(finNeg1,ImgN1);
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);
int a,b,c,d;
if(r.tl().x>=0) a=r.tl().x;
else a=0;
if(r.tl().y>=0) b=r.tl().y;
else b=0;
if(r.br().x>src.cols) c=src.cols;
else c=r.br().x;
if(r.br().y>src.rows) d=src.rows;
else d=r.br().y;
Rect myROI(a,b,c-a,-b+d);
cout<<myROI;
Mat croppedImage=src(myROI);
imwrite(ImgN1,croppedImage);
}
}
/*************************************************/
/****************** Read in a single 64*128 Test diagram of and test it HOG Descriptors for classification *********************/
Read the test picture (64*128 size ), And calculate it HOG Narrator
Mat testImg = imread("person014142.jpg");
//Mat testImg = imread("noperson000026.jpg");
//vector<float> descriptor;
//hog.compute(testImg,descriptor,Size(8,8));// Calculation HOG Narrator , Detection window moving step size (8,8)
//Mat testFeatureMat = Mat::zeros(1,3780,CV_32FC1);// The eigenvector matrix of the test sample
The calculated HOG The descriptor is copied to testFeatureMat Matrix
//for(int i=0; i<descriptor.size(); i++)
// testFeatureMat.at<float>(0,i) = descriptor[i];
With training SVM The classifier classifies the feature vectors of the test image
//int result = svm.predict(testFeatureMat);// Returns the class label
//cout<<" Classification results :"<<result<<endl;
system("pause");
}test.cpp
//
// main.cpp
// car
//
// Created by ymy on 16/3/15.
// Copyright 2016 year ymy. All rights reserved.
//
#include <iostream>
#include <stdio.h>
#include <cv.h>
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
using namespace std;
using namespace cv;
void detectAndDisplay( Mat frame );
//String car_cascade_name = "/Users/ymy/Desktop/SVM_HOG.xml";//california
//String car_cascade_name = "/Users/ymy/Desktop/UIUC/cas2.xml";//UIUC
String car_cascade_name = "/Users/ymy/Documents/SJTU_bachelor/PRP/car_detection/code/car/cars.xml";
CascadeClassifier car_cascade;
string window_name = "Capture - car detection";
RNG rng(12345);
int main(int argc, const char * argv[]) {
//VideoCapture cap("/Users/ymy/Documents/SJTU_bachelor/PRP/car_detection/traffic.avi");// Car front detection for video processing
Mat frame;
frame = imread("/Users/ymy/Documents/SJTU_bachelor/PRP/car_detection/example.jpg");
//if( !car_cascade.load( car_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
car_cascade.load( car_cascade_name );
//-- 2. Read the video stream
//detectAndDisplay( frame );
// Read video
/*for(;;)
{
cap >> frame;
if( !frame.empty() )
{ detectAndDisplay( frame ); }
else
{ printf(" --(!) No captured frame -- Break!"); break; }
int c = waitKey(10);
if( (char)c == 'c' ) { break; }
}*/
waitKey(0);
return 0;
}
void detectAndDisplay( Mat frame )
{
std::vector<Rect> cars;
Mat frame_gray;
//VideoWriter out;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
//-- Detect car
car_cascade.detectMultiScale( frame_gray, cars, 1.1, 1, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( size_t i = 0; i < cars.size(); i++ )
{
if(cars[i].width<130 or cars[i].height<65) continue;
Point center( cars[i].x + cars[i].width*0.5, cars[i].y + cars[i].height*0.5 );
ellipse( frame, center, Size( cars[i].width*0.5, cars[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
Mat faceROI = frame_gray( cars[i] );
}
//-- Show what you got
imshow( window_name, frame );
imwrite("/Users/ymy/Documents/SJTU_bachelor/PRP/car_detection/result.jpg",frame);
}
边栏推荐
- Heketi record
- Asp .NetCore 微信订阅号自动回复之文本篇
- How to solve the image pop-up problem when pycharm calls Matplotlib to draw
- How to realize parallel replication in MySQL replication
- Resumption of attack and defense drill
- Difficult to get up syndrome (bit by bit greed)
- Graduation season | Huawei experts teach the interview secret: how to get a high paying offer from a large factory?
- PWN attack and defense world cgpwn2
- 毕业季 | 华为专家亲授面试秘诀:如何拿到大厂高薪offer?
- .env.xxx 文件,加了常量,却undefined
猜你喜欢
![[QT] qtcreator uninstall and installation (abnormal state)](/img/66/1b96326d87bca2a790a6694f38e79e.png)
[QT] qtcreator uninstall and installation (abnormal state)

九州云与英特尔联合发布智慧校园私有云框架,赋能教育新基建

【QT】测试Qt是否能连接上数据库
![Jielizhi, production line assembly link [chapter]](/img/f8/20c41ffe9468d59bf25ea49f73751e.png)
Jielizhi, production line assembly link [chapter]

GCC compilation

Dongge cashes in and the boss retires?

【CMake】Qt creator 里面的 cmake 配置

UDS bootloader of s32kxxx bootloader

- Oui. Env. Fichier XXX, avec constante, mais non spécifié

LDR6035智能蓝牙音响可对手机设备持续充放电方案
随机推荐
Shell process control
Use the htaccess file to prohibit the script execution permission in the directory
Vue force cleaning browser cache
MySQL: the difference between insert ignore, insert and replace
PyTorch学习记录
Heketi record
How to improve data quality
实例讲解将Graph Explorer搬上JupyterLab
下载在线视频 m3u8使用教程
Ldr6035 smart Bluetooth audio can be charged and released (5.9.12.15.20v) fast charging and fast releasing device charging
LDR6035智能蓝牙音响可对手机设备持续充放电方案
How to solve the image pop-up problem when pycharm calls Matplotlib to draw
.env.xxx 文件,加了常量,卻undefined
如何提升数据质量
ADO. Net SqlConnection object usage summary
Database -- sqlserver details
Is the securities account given by qiniu business school safe? Where can I open an account
Selectively inhibiting learning bias for active sampling
Asp . Text of automatic reply to NETCORE wechat subscription number
4. Object mapping Mapstercover