当前位置:网站首页>【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);
}
边栏推荐
- The origin of usb-if Association and various interfaces
- Mysql database driver (JDBC Driver) jar package download
- LeetCode中等题题分享(5)
- Jielizhi Bluetooth headset quality control and production skills [chapter]
- [Qt] résoudre le problème que Qt msvc 2017 ne peut pas Compiler
- 数据分析方法论与前人经验总结【笔记干货】
- vs2015 AdminDeployment. xml
- Asp . Text of automatic reply to NETCORE wechat subscription number
- Node——添加压缩文件
- Digital transformation has a long way to go, so how to take the key first step
猜你喜欢

S32Kxxx bootloader之UDS bootloader

Leetcode medium question sharing (5)

Database -- sqlserver details

.env.xxx 文件,加了常量,卻undefined
![Data analysis methodology and previous experience summary [notes dry goods]](/img/00/e4c4cf37f1ca9134546f970d800226.png)
Data analysis methodology and previous experience summary [notes dry goods]

Gaussdb (for MySQL):partial result cache, which accelerates the operator by caching intermediate results

LDR6035智能蓝牙音响可充可放(5.9.12.15.20V)快充快放设备充电

【QT】QtCreator卸载与安装(非正常状态)

电商RPA机器人,助力品牌电商抢立流量高点

What is ThreadLocal memory leak and how to solve it
随机推荐
Selectively inhibiting learning bias for active sampling
Kyushu cloud and Intel jointly released the smart campus private cloud framework, enabling new infrastructure for education
Relatively easy to understand PID understanding
Algolia's search needs are almost closed
基于全志H3的QT5.12.9移植教程
Graduation season | Huawei experts teach the interview secret: how to get a high paying offer from a large factory?
Graduation season is both a farewell and a new beginning
cookie、session、tooken
起床困难综合症(按位贪心)
Leetcode 96 différents arbres de recherche binaires
时间复杂度与空间复杂度
LDR6035智能蓝牙音响可对手机设备持续充放电方案
Node——添加压缩文件
Linux centos7 installation Oracle11g super perfect novice tutorial
Window sorting functions rank and deny for SQL data analysis_ rank、raw_ Number and lag, lead window offset function [usage sorting]
Digital transformation has a long way to go, so how to take the key first step
cookie、session、tooken
Asp . Text of automatic reply to NETCORE wechat subscription number
Iota in golang
I would like to ask, which securities is better for securities account opening? Is it safe to open a mobile account?