当前位置:网站首页>【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);
}
边栏推荐
- Use pair to do unordered_ Key value of map
- 【mysql 07】GPG key retrieval failed: “Couldn‘t open file /etc/pki/rpm-gpg/RPM-GPG-KEY-mysql-2022“
- 电商RPA机器人,助力品牌电商抢立流量高点
- - Oui. Env. Fichier XXX, avec constante, mais non spécifié
- Dongge cashes in and the boss retires?
- What is ThreadLocal memory leak and how to solve it
- What is the purpose of ERP project implementation plan?
- 【QT】對於Qt MSVC 2017無法編譯的問題解决
- [QT] QT cannot find a solution to the compiler using msvc2017
- Mysql database driver (JDBC Driver) jar package download
猜你喜欢

多表操作-一对一,一对多与多对多

使用多线程Callable查询oracle数据库
![Flow control statement of SQL data analysis [if, case... When detailed]](/img/7b/eabb0700936d34a3a145737580be88.png)
Flow control statement of SQL data analysis [if, case... When detailed]

Halcon knowledge: an attempt of 3D reconstruction

Leetcode 96 différents arbres de recherche binaires

下载在线视频 m3u8使用教程
![Comprehensive usage and case questions of sub query of SQL data analysis [patient sorting]](/img/24/d9a48a0f76cde65421edda04d0f854.png)
Comprehensive usage and case questions of sub query of SQL data analysis [patient sorting]

Graduation season | Huawei experts teach the interview secret: how to get a high paying offer from a large factory?

RPA tutorial 01: Excel automation from introduction to practice

Review data desensitization system
随机推荐
Ldr6035 smart Bluetooth audio can continuously charge and discharge mobile devices
UDS bootloader of s32kxxx bootloader
Practical calculation of the whole process of operational amplifier hysteresis comparator
[QT] QT cannot find a solution to the compiler using msvc2017
Operate database transactions with jpatractionmanager
Multi table operation - one to one, one to many and many to many
Graduation season is both a farewell and a new beginning
.env.xxx 文件,加了常量,卻undefined
Shell custom function
What is ThreadLocal memory leak and how to solve it
Use vb Net to convert PNG pictures into icon type icon files
SQL数据分析之窗口排序函数rank、dense_rank、raw_number与lag、lead窗口偏移函数【用法整理】
Accelerator systems initiative is an independent non-profit organization
Relatively easy to understand PID understanding
Download the online video m3u8 tutorial
数据分析方法论与前人经验总结【笔记干货】
13 MySQL constraint
RPA tutorial 01: Excel automation from introduction to practice
Why does blocprovider feel similar to provider?
Asp .NetCore 微信订阅号自动回复之文本篇