#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <sys/types.h>
#include <dirent.h>
#include <opencv2/ml.hpp>
#define IMG_COUNT 4564
using namespace std;
using namespace cv;
using namespace ml;
void load_img(float*& sample, float*& label, int tag, string path, bool& is_init, int& line_len) {
HOGDescriptor hog(Size(64,64), Size(16,16), Size(8,8), Size(8,8), 9);
DIR* dir = nullptr;
struct dirent* file = nullptr;
int count = 0;
if( (dir = opendir(path.data())) ) {
string cur = ".", par = "..";
while( (file=readdir(dir)) != nullptr) {
if(file->d_name != cur && file->d_name != par) {
string real_path = path + file->d_name;
// cout << real_path << endl;
Mat img = imread(real_path);
cvtColor(img, img, COLOR_BGR2GRAY);
vector<float> v;
hog.compute(img, v);
if(!is_init) {
line_len = v.size();
sample = new float[IMG_COUNT*line_len];
label = new float[IMG_COUNT*1];
is_init = true;
}
for(int k=0; k<line_len; k++) *(sample+line_len*count+k) = v[k];
label[count] = tag;
count ++;
}
}
}
}
void train_svm() {
float* sample, *label;
bool is_init = false;
int line_len;
load_img(sample, label, 1, "/mnt/majiao_work/Xubuntu_Work_Space/From_Xubuntu/xubuntu_蓝牙文件/vehicles/GTI_Right/", is_init, line_len);
load_img(sample, label, -1, "/mnt/majiao_work/Xubuntu_Work_Space/From_Xubuntu/xubuntu_蓝牙文件/non-vehicles/GTI/", is_init, line_len);
Mat sampleMat(IMG_COUNT, line_len, CV_32FC1, sample);
Mat labelMat(IMG_COUNT, 1, CV_32SC1, label);
imshow("sampleMat", sampleMat); waitKey();
Ptr<ml::SVM> svm = ml::SVM::create();
svm->setType(SVM::Types::C_SVC);
svm->setKernel(SVM::KernelTypes::LINEAR);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 20000, 1e-6));
cout << "start train ..." << endl;
svm->train(sampleMat, ROW_SAMPLE, labelMat);
svm->save("car.xml");
cout << "train ok" << endl;
delete sample;
delete label;
}
void detech_car(string& path) {
Ptr<ml::SVM> svm = ml::SVM::load("car.xml");
Mat svMat = svm->getSupportVectors();
int svDim = svm->getVarCount();
int numOfSv = svMat.rows;
Mat alphaMat = Mat::zeros(numOfSv, svDim, CV_32F);
Mat svIndex = Mat::zeros(1, numOfSv, CV_64F);
Mat result;
double rho = svm->getDecisionFunction(0, alphaMat, svIndex);
alphaMat.convertTo(alphaMat, CV_32F);
result = -1 * alphaMat*svMat;
cout << "83" << endl;
vector<float> vec;
for(int i=0; i<svDim; i++) {
vec.push_back(result.at<float>(0,i));
}
vec.push_back(rho);
HOGDescriptor hog(Size(64,64), Size(16,16), Size(8,8), Size(8,8), 9);
hog.setSVMDetector(vec);
Mat img = imread(path);
cout << path << endl;
vector<Rect> v;
hog.detectMultiScale(img, v);
for(int i=0; i<v.size(); i++) {
rectangle(img, v[i], Scalar(0,0,255));
putText(img, "car", v[i].tl(), 2, 2, Scalar(255,0,0));
}
imshow("", img); waitKey();
}
int main(void) {
// train_svm();
string path = "/mnt/majiao_work/Xubuntu_Work_Space/From_Xubuntu/codeTest_2019_2_21/QT_Opencv_Study/car.jpeg";
detech_car(path);
return 0;
}