#include<iostream>
#include<fstream>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/objdetect/objdetect.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/ml/ml.hpp>
using namespace std;
using namespace cv;
using namespace cv::ml;
#define PosSamNO 8792 //正樣本個數
#define NegSamNO 8968 //負樣本個數
#define TRAIN true
#define CENTRAL_CROP true
int main()
{
HOGDescriptor hog(Size(64,64),Size(16,16),Size(8,8),Size(8,8),9);
int DescriptorDim;
Ptr<SVM> svm = SVM::create();
if (TRAIN)
{
string ImgName;
ifstream finPos("pos.txt");
ifstream finNeg("neg.txt");
if (!finPos || !finNeg)
{
cout << "Pos/Neg imglist reading failed..." << endl;
return 1;
}
Mat sampleFeatureMat;
Mat sampleLabelMat;
//loading original positive examples...
for (int num = 0; num < PosSamNO && getline(finPos, ImgName); num++)
{
cout << "Now processing original positive image: " << ImgName << endl;
ImgName = "DATA\\positive\\" + ImgName;
Mat src = imread(ImgName);
/*if (CENTRAL_CROP)
src = src(Rect(16,16,64,64));*/
vector<float> descriptors;
hog.compute(src, descriptors, Size(4,4)); //計算hog描述子,檢測視窗移動步長(8,8)
//cout << "go" << endl;
if (0 == num)
{
DescriptorDim = descriptors.size();
sampleFeatureMat = Mat::zeros(PosSamNO + NegSamNO, DescriptorDim, CV_32FC1);
sampleLabelMat = Mat::zeros(PosSamNO + NegSamNO, 1, CV_32FC1);
//sampleLabelMat的資料型別必須為有符號整數
}
//將計算好的HOG描述子復制到樣本特征矩陣sampleFeatureMat
for (int i = 0; i < DescriptorDim; i++)
sampleFeatureMat.at<float>(num, i) = descriptors[i];
sampleLabelMat.at<int>(num, 0) = 1;
}
finPos.close();
//loading original negtive examples...
for (int num = 0; num < NegSamNO && getline(finNeg, ImgName); num++)
{
cout << "Now processing original negtive image: " << ImgName << endl;
ImgName = "DATA\\negtive\\" + ImgName;
Mat src = imread(ImgName);
vector<float> descriptors;
hog.compute(src, descriptors, Size(4,4));
for (int i = 0; i < DescriptorDim; i++)
sampleFeatureMat.at<float>(num + PosSamNO, i) = descriptors[i];
sampleLabelMat.at<int>(num + PosSamNO, 0) = -1;
}
finNeg.close();
svm->setType(SVM::C_SVC);
svm->setC(0.01);
svm->setKernel(SVM::LINEAR);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 3000, 1e-6));
cout << "Starting training..." << endl;
svm->train(sampleFeatureMat, ROW_SAMPLE, sampleLabelMat);
cout << "Finishing training..." << endl;
svm->save("SVM_HOG.xml");
cout << "SVM_HOG.xml have saved!" << endl;
}
else
{
//svm = SVM::load < cv::ml::SVM > ("SVM_HOG.xml"); //或者svm = Statmodel::load<SVM>("SVM_HOG.xml"); static function
// svm->load<SVM>("SVM_HOG.xml"); 這樣使用不行
//vm.load("SVM_HOG.xml");
Ptr < ml::SVM >svm = ml::SVM::load("SVM_HOG.xml");
}
Mat svecsmat = svm->getSupportVectors();//svecsmat元素的資料型別為float
int svdim = svm->getVarCount();//特征向量位數
int numofsv = svecsmat.rows;
Mat alphamat = Mat::zeros(numofsv, svdim, CV_32F);//alphamat和svindex必須初始化,否則getDecisionFunction()函式會報錯
Mat svindex = Mat::zeros(1, numofsv, CV_64F);
Mat Result;
double rho = svm->getDecisionFunction(0, alphamat, svindex);
alphamat.convertTo(alphamat, CV_32F);//將alphamat元素的資料型別重新轉成CV_32F
Result = -1 * alphamat * svecsmat;//float
vector<float> vec;
for (int i = 0; i < svdim; ++i)
{
vec.push_back(Result.at<float>(0, i));
}
vec.push_back(rho);
//saving HOGDetectorForOpenCV.txt
ofstream fout("HOGDetectorForOpenCV.txt");
for (int i = 0; i < vec.size(); ++i)
{
fout << vec[i] << endl;
}
return 0;
}
uj5u.com熱心網友回復:
看看哪句報錯,逐句除錯,在根據錯誤資訊修改,加油(? ??_??)?還有就是,求助貼一般會把錯誤資訊也貼上來,直接一大段代碼沒什么人會仔細去看的。。。
uj5u.com熱心網友回復:
謝謝,剛才看了一下,我發現我的src是空的,好像還是圖片的路徑有問題,
uj5u.com熱心網友回復:
可以把路徑列印出來對比下uj5u.com熱心網友回復:
嗯嗯,謝謝你,今天調了一天,代碼基本沒問題了,就是識別的效果不太好,可能是我的訓練樣本不是很好,不是很清晰,我又要重新找樣本來試試
uj5u.com熱心網友回復:
嗯嗯 加油
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/68362.html
標籤:機器視覺
下一篇:tf模型轉換tf.lite報錯
