日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

svm图片多分类python代码_[OpenCV随笔]-OpenCV3.x中SVM多分类使用(代码篇)

發(fā)布時(shí)間:2023/12/9 python 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 svm图片多分类python代码_[OpenCV随笔]-OpenCV3.x中SVM多分类使用(代码篇) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. SVM介紹

占個(gè)坑,以后再說

2. OpenCV3.x下SVM接口介紹

官方文檔

OpenCV3.x與OpenCV2.x中SVM的接口有了很大變化,在接口上使用了虛函數(shù)取代以前的定義。

下面介紹幾個(gè)常用的接口,及其參數(shù)意義。

2.1 初始化函數(shù)

定義如下:

CV_WRAP static Ptr create();

2.2 參數(shù)設(shè)置函數(shù)

然后是一些設(shè)置SVM參數(shù)的函數(shù):

CV_WRAP virtual int getType() const = 0;

CV_WRAP virtual void setType(int val) = 0;

CV_WRAP virtual double getGamma() const = 0;

CV_WRAP virtual void setGamma(double val) = 0;

CV_WRAP virtual double getDegree() const = 0;

CV_WRAP virtual void setDegree(double val) = 0;

CV_WRAP virtual double getC() const = 0;

CV_WRAP virtual void setC(double val) = 0;

CV_WRAP virtual double getNu() const = 0;

CV_WRAP virtual void setNu(double val) = 0;

CV_WRAP virtual double getP() const = 0;

CV_WRAP virtual void setP(double val) = 0;

CV_WRAP virtual cv::Mat getClassWeights() const = 0;

CV_WRAP virtual void setClassWeights(const cv::Mat &val) = 0;

CV_WRAP virtual cv::TermCriteria getTermCriteria() const = 0;

CV_WRAP virtual void setTermCriteria(const cv::TermCriteria &val) = 0;

CV_WRAP virtual int getKernelType() const = 0;

CV_WRAP virtual void setKernel(int kernelType) = 0;

具體的作用可以參考OpenCV文檔,這里只介紹兩個(gè)常用的函數(shù):

//設(shè)置SVM類型

CV_WRAP virtual int getType() const = 0;

這個(gè)函數(shù)用于設(shè)置SVM類型,OpenCV提供了五種類型:

Types {

//C類支持向量分類機(jī)。 n類分組 (n≥2),容許用異常值處罰因子C進(jìn)行不完全分類。

C_SVC =100,

//$v$類支持向量機(jī)

NU_SVC =101,

//單分類器,所有的練習(xí)數(shù)據(jù)提取自同一個(gè)類里,

//然后SVM建樹了一個(gè)分界線以分別該類在特點(diǎn)空間

//中所占區(qū)域和其它類在特點(diǎn)空間中所占區(qū)域。

ONE_CLASS =102,

EPS_SVR =103,

NU_SVR =104

}

一般我們使用SVM進(jìn)行二分類或者多分類任務(wù),選擇第一種SVM::C_SVC即可。

還有一個(gè)函數(shù)就是:

CV_WRAP virtual void setKernel(int kernelType) = 0;

這個(gè)函數(shù)用于設(shè)置SVM的核函數(shù)類型,我們知道,通過選擇SVM的核函數(shù)可以使SVM處理高階、非線性問題。OpenCV提供幾種核函數(shù):

enum KernelTypes {

/** Returned by SVM::getKernelType in case when custom kernel has been set */

CUSTOM=-1,

//線性核

LINEAR=0,

//多項(xiàng)式核

POLY=1,

//徑向基核(高斯核)

RBF=2,

//sigmoid核

SIGMOID=3,

//指數(shù)核,與高斯核類似

CHI2=4,

//直方圖核

INTER=5

};

一般情況下使用徑向基核可以很好處理大部分情況。

2.3 訓(xùn)練函數(shù)

OpenCV3.x中SVM的提供了訓(xùn)練函數(shù)也與2.x不同,如下:

virtual bool trainAuto( const Ptr& data, int kFold = 10,

ParamGrid Cgrid = getDefaultGrid(C),

ParamGrid gammaGrid = getDefaultGrid(GAMMA),

ParamGrid pGrid = getDefaultGrid(P),

ParamGrid nuGrid = getDefaultGrid(NU),

ParamGrid coeffGrid = getDefaultGrid(COEF),

ParamGrid degreeGrid = getDefaultGrid(DEGREE),

bool balanced=false) = 0;

bool trainAuto (InputArray samples, int layout, InputArray responses,

int kFold=10, Ptr< ParamGrid > Cgrid=SVM::getDefaultGridPtr(SVM::C),

Ptr< ParamGrid > gammaGrid=SVM::getDefaultGridPtr(SVM::GAMMA),

Ptr< ParamGrid > pGrid=SVM::getDefaultGridPtr(SVM::P),

Ptr< ParamGrid > nuGrid=SVM::getDefaultGridPtr(SVM::NU),

Ptr< ParamGrid > coeffGrid=SVM::getDefaultGridPtr(SVM::COEF),

Ptr< ParamGrid > degreeGrid=SVM::getDefaultGridPtr(SVM::DEGREE),

bool balanced=false)

trainAuto可以在訓(xùn)練過程中自動(dòng)優(yōu)化2.2中的那些參數(shù),而使用train函數(shù)時(shí),參數(shù)被固定,所以推薦使用trainAuto函數(shù)。

在準(zhǔn)備訓(xùn)練數(shù)據(jù)的時(shí)候,有下面幾點(diǎn)需要注意,否則函數(shù)會(huì)報(bào)錯(cuò)

SVM的訓(xùn)練函數(shù)是ROW_SAMPLE類型的,也就是說,送入SVM訓(xùn)練的特征需要reshape成一個(gè)行向量,所有訓(xùn)練數(shù)據(jù)全部保存在一個(gè)Mat中,一個(gè)訓(xùn)練樣本就是Mat中的一行,最后還要講這個(gè)Mat轉(zhuǎn)換成CV_32F類型,例如,如果有\(zhòng)(k\)個(gè)樣本,每個(gè)樣本原本維度是\((h, w)\),則轉(zhuǎn)換后Mat的維度為\((k, h * w)\)

對(duì)于多分類問題,label矩陣的行數(shù)要與樣本數(shù)量一致,也就是每個(gè)樣本要在label矩陣中有一個(gè)對(duì)應(yīng)的標(biāo)簽,label的列數(shù)為1,因?yàn)閷?duì)于一個(gè)樣本,SVM輸出一個(gè)值,我們?cè)谟?xùn)練前需要做的就是設(shè)計(jì)這個(gè)值與樣本的對(duì)應(yīng)關(guān)系。對(duì)于有\(zhòng)(k\)個(gè)樣本的情況,label的維度是\((k, 1)\)

2.4 預(yù)測(cè)函數(shù)

函數(shù)定義如下:

float predict(cv::InputArrat samples, cv::OutputArray results = noArray(), int flags = 0) const;

其中samples就是需要預(yù)測(cè)的樣本,這里樣本同樣要轉(zhuǎn)換成ROW_SAMPLE和CV_32F格式,對(duì)于單個(gè)測(cè)試樣本的情況,預(yù)測(cè)結(jié)果直接通過函數(shù)返回值返回,而如果samples中有多個(gè)樣本,就需要穿進(jìn)result參數(shù),預(yù)測(cè)結(jié)果以列向量的方式保存在result數(shù)組中。假如有\(zhòng)(k\)個(gè)樣本,每個(gè)樣本原本的維度為\((h, w)\),則samples的維度為\((k, h * w)\),最終預(yù)測(cè)結(jié)果result維度為\((k, 1)\)

3. 例程

下面上代碼:

/*

* 把圖片從vector格式轉(zhuǎn)換成SVM的RAW_SAMPLE格式

*/

void transform(const vector &split, Mat &testData)

{

for (auto it = split.begin(); it != split.end(); it++){

Mat tmp;

resize(*it, tmp, Size(28, 28));

testData.push_back(tmp.reshape(0, 1));

}

testData.convertTo(testData, CV_32F);

}

/*

* 從文件list.txt中讀取測(cè)試數(shù)據(jù)和標(biāo)簽,輸出SVM的Mat格式

*/

void get_data(string path, Mat &trainData, Mat &trainLabels)

{

fstream io(path, ios::in);

if (!io.is_open()){

cout << "file open error in path : " << path << endl;

exit(0);

}

while (!io.eof())

{

string msg;

io >> msg;

trainData.push_back(imread(msg, 0).reshape(0, 1));

io >> msg;

int idx = msg[0] - '0';

//trainLabels.push_back(Mat_(1, 1) << idx); //用這種方式會(huì)報(bào)錯(cuò),原因尚且不明

trainLabels.push_back(Mat(1, 1, CV_32S, &idx));

}

trainData.convertTo(trainData, CV_32F);

}

/*

* 訓(xùn)練SVM

*/

void svm_train(Ptr &model, Mat &trainData, Mat &trainLabels)

{

model->setType(SVM::C_SVC); //SVM類型

model->setKernel(SVM::LINEAR); //核函數(shù),這里使用線性核

Ptr tData = TrainData::create(trainData, ROW_SAMPLE, trainLabels);

cout << "SVM: start train ..." << endl;

model->trainAuto(tData);

cout << "SVM: train success ..." << endl;

}

/*

* 利用訓(xùn)練好的SVM預(yù)測(cè)

*/

void svm_pridect(Ptr &model, Mat test)

{

Mat result;

float rst = model->predict(test, result);

for (auto i = 0; i < result.rows; i++){

cout << result.at(i, 0);

}

}

int main(int argc, const char** argv)

{

fstream io;

io.open("test_list.txt", ios::in);

string train_path = "train_list.txt";

vector test_set;

get_test(io, test_set);

Ptr model = SVM::create();

Mat trainData, trainLabels;

get_data(train_path, trainData, trainLabels);

svm_train(model, trainData, trainLabels);

Mat testData;

transform(test_set, testData);

svm_pridect(model, testData);

}

trian_list.txt文件格式是這樣的:

D:\ImgPro\Project\for\char\code\beta00\train_data\0\0-1.jpg0

D:\ImgPro\Project\for\char\code\beta00\train_data\0\0-2.jpg0

每行前一段表示訓(xùn)練圖片地址,最后的數(shù)字表示這個(gè)圖片對(duì)應(yīng)標(biāo)簽

test_list.txt中格式與train_list.txt差不多,只是沒有了標(biāo)簽。

總結(jié)

以上是生活随笔為你收集整理的svm图片多分类python代码_[OpenCV随笔]-OpenCV3.x中SVM多分类使用(代码篇)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。