機器學習-SVM實例

#include <iostream> /<iostream>

#include <fstream> /<fstream>

#include <opencv2> /<opencv2>

#include <opencv2> /<opencv2>

#include <opencv2> /<opencv2>

#include <opencv2> /<opencv2>

#include <opencv2> /<opencv2>

#define PosSamNum 100 //正樣本個數

#define NegSamNum 100 //負樣本個數

std::string train_image_folder = "./";

std::string test_image_folder = "./";

void train(){

std::cout<

std::ifstream train_pos_file(train_image_folder + "train/pos.lst");

std::ifstream train_neg_file(train_image_folder + "train/neg.lst");

std::string image_name; //圖片路徑

cv::Mat src;

//定義HOG檢測器

int descriptor_dim = 0;

//檢測窗口(64,128),塊尺寸(16,16),塊步長(8,8),cell尺寸(8,8),直方圖bin個數9

cv::HOGDescriptor hog(cv::Size(64,128),cv::Size(16,16),cv::Size(8,8),cv::Size(8,8),9);//HOG檢測器,用來計算HOG描述子的

std::vector<float> descriptors; //HOG描述子向量/<float>

cv::Mat sample_features; //所有訓練樣本的特徵向量組成的矩陣,行數等於所有樣本的個數,列數等於HOG描述子維數

cv::Mat sample_labels; //訓練樣本的類別向量,行數等於所有樣本的個數,列數等於1;1表示有人,-1表示無人

//獲取訓練數據的正樣本

for(int num=0; num<possamnum>

{

image_name = train_image_folder + image_name;

src = cv::imread(image_name,0);

cv::resize(src,src,cv::Size(96,160)); //統一訓練格式

if(src.empty()){

std::cout<

exit(0);

}

hog.compute(src,descriptors,cv::Size(8,8));

if(num==0){

std::cout<

descriptor_dim = descriptors.size();

sample_features = cv::Mat::zeros(PosSamNum+NegSamNum,descriptor_dim,CV_32FC1);

sample_labels = cv::Mat::zeros(PosSamNum+NegSamNum,1,CV_32SC1); //注意這裡必須要32SC1,不能用32FC1

}

for(int i=0;i<descriptor>

sample_features.at<float>(num,i) = descriptors[i];/<float>

}

sample_labels.at

(num,0) = 1; //正樣本類別為1,有人

std::cout<

}

//獲取訓練數據的負樣本

for(int num=0;num<negsamnum>

image_name = train_image_folder + image_name;

src = cv::imread(image_name,0);

if(src.empty()){

std::cout<

exit(0);

}

cv::resize(src,src,cv::Size(96,160));

hog.compute(src,descriptors,cv::Size(8,8));

for(int i=0;i<descriptor>

sample_features.at<float>(num+PosSamNum,i) = descriptors[i];/<float>

}

sample_labels.at(num+PosSamNum,0) = -1; //正樣本類別為-1,沒有人

std::cout<

}

//訓練SVM分類器

std::cout<

cv::Ptr<:ml::svm> svm = cv::ml::SVM::create();

svm->setType(cv::ml::SVM::C_SVC);

svm->setKernel(cv::ml::SVM::LINEAR);

svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, 100, 1e-6));

svm->train(sample_features,cv::ml::ROW_SAMPLE,sample_labels);

//保存SVM分類器

std::cout<

svm->save("test_svm.xml");

std::cout<

return;

}

void test(std::string test_image_name){

std::cout<

//加載圖片

cv::Mat test_image = cv::imread(test_image_name,0);

if(test_image.empty()){

std::cout<

return;

}

//獲取特徵並組織為單行的格式

cv::resize(test_image,test_image,cv::Size(96,160)); //訓練樣本的尺寸是(96,160),修改訓練數據後,要同步修改

cv::HOGDescriptor hog(cv::Size(64,128),cv::Size(16,16),cv::Size(8,8),cv::Size(8,8),9);

std::vector<float> descriptors;/<float>

hog.compute(test_image,descriptors,cv::Size(8,8));

cv::Mat test_feature = cv::Mat::zeros(1,descriptors.size(),CV_32FC1);

for(int i=0;i<descriptors.size>

test_feature.at<float>(0,i) = descriptors[i];/<float>

}

//加載SVM

cv::Ptr<:ml::svm> svm = cv::ml::SVM::create();

svm = cv::ml::SVM::load("./test_svm.xml");

//如果文件不存在則先訓練

if(svm.empty()){

train();

}

//輸出結果

cv::Mat result;

svm->predict(test_feature,result);

float res = result.at<float>(0,0);/<float>

if(res==1){

std::cout<

}else if(res==-1){

std::cout<

}

return;

}

int main(int argc,char* argv[]){

if(strcmp(argv[1],"train")==0){

train();

return 0;

}

if(strcmp(argv[1],"test")==0){

if(argc<3){

std::cout<

return 1;

}

test(argv[2]);

return 0;

}

}

"/<descriptors.size>

/<descriptor>

/<negsamnum>

/<descriptor>

/<possamnum>


分享到:


相關文章: