【轉(zhuǎn)載】用opencv中svm分割圖像

https://blog.csdn.net/shi923281339/article/details/77094757


1.理解SVM

請移步支持向量機(jī)通俗導(dǎo)論腥椒,通俗易懂月腋,這里不在贅述纤垂。

2.opencv中的SVM

opencv中對svm的介紹:Support Vector Machines for Non-Linearly Separable Data

官方測試代碼:我做了詳細(xì)的標(biāo)注:

#include <opencv2/core.hpp>

#include <opencv2/imgproc.hpp>

#include "opencv2/imgcodecs.hpp"

#include <opencv2/highgui.hpp>

#include <opencv2/ml.hpp>

#include <iostream>

using namespace std;

using namespace cv;

using namespace cv::ml;

int main(int, char**)

{

? ? // Data for visual representation

? ? int width = 512, height = 512;

? ? // zeros就是搞成全0矩陣

? ? Mat image = Mat::zeros(height, width, CV_8UC3);

? ? // Set up training data

? ? //! [setup1]

? ? //設(shè)置訓(xùn)練數(shù)據(jù)

? ? int labels[4] = { 1, -1, -1, -1 };? // 每個樣本點對應(yīng)的類

? ? float trainingData[4][2] = { { 501, 10 }, { 255, 10 }, { 501, 255 }, { 10, 501 } };

? ? //! [setup1]

? ? //! [setup2]

? ? // 將訓(xùn)練數(shù)據(jù)存入浮點型Mat中

? ? Mat trainingDataMat(4, 2, CV_32FC1, trainingData);

? ? // 使用OpenCV里面的機(jī)器學(xué)習(xí)算法時,要保證給的labelData的數(shù)據(jù)格式為”有符號的整型數(shù)”,

? ? // ”CV_32FC1”就是錯誤的一種形式倦沧,應(yīng)該使用”CV_32SC1”

? ? Mat labelsMat(4, 1, CV_32SC1, labels);

? ? //! [setup2]

? ? // Train the SVM

? ? //! [init]

? ? // 這里的svm是一個指針

? ? Ptr<SVM> svm = SVM::create();

? ? svm->setType(SVM::C_SVC);? // 文本選擇

? ? svm->setKernel(SVM::LINEAR);

? ? // TermCriteria是一個結(jié)構(gòu)體蔗怠,包括終止的類型墩弯,迭代次數(shù)或者元素數(shù)量,精度寞射。

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

? ? //! [init]

? ? //! [train],ROW_SAMPLE指每次訓(xùn)練樣本的一行

? ? // 因此總的意思是每次訓(xùn)練樣本的一行渔工,而這一行是哪一類是由labelsMat決定的

? ? svm->train(trainingDataMat, ROW_SAMPLE, labelsMat);

? ? //! [train]

? ? // Show the decision regions given by the SVM

? ? //! [show]

? ? Vec3b green(0, 255, 0), blue(255, 0, 0);

? ? for (int i = 0; i < image.rows; ++i)

? ? ? ? for (int j = 0; j < image.cols; ++j)

? ? ? ? {

? ? ? ? ? ? Mat sampleMat = (Mat_<float>(1, 2) << j, i);

? ? ? ? ? ? float response = svm->predict(sampleMat);

? ? ? ? ? ? if (response == 1)

? ? ? ? ? ? ? ? image.at<Vec3b>(i, j) = green;

? ? ? ? ? ? else if (response == -1)

? ? ? ? ? ? ? ? image.at<Vec3b>(i, j) = blue;

? ? ? ? }

? ? //! [show]

? ? // Show the training data

? ? //! [show_data]

? ? int thickness = -1;? ? // 實心圓

? ? int lineType = 8;

? ? circle(image, Point(501, 10), 5, Scalar(0, 0, 0), thickness, lineType);

? ? circle(image, Point(255, 10), 5, Scalar(255, 255, 255), thickness, lineType);

? ? circle(image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType);

? ? circle(image, Point(10, 501), 5, Scalar(255, 255, 255), thickness, lineType);

? ? //! [show_data]

? ? // Show support vectors

? ? //! [show_vectors]

? ? thickness = 2;? ? // 線寬為2的圓

? ? lineType = 8;

? ? // 輸出所有的支持向量

? ? //int c = svm->getVarCount();? ? // 獲得支持向量的維數(shù)

? ? //cout << c << endl;

? ? Mat sv = svm->getSupportVectors();

? ? //cout << sv.cols << "-" << sv.rows << endl;

? ? // 訓(xùn)練出來的SVM classifier的support vector是以Mat類型進(jìn)行存儲,

? ? //其rows是根據(jù)svm的參數(shù)而變化的桥温,如果是二分類分類器引矩,應(yīng)該是1*n的大小。

? ? // 這里一行存的坐標(biāo)。

? ? for (int i = 0; i < sv.rows ; ++i)

? ? {

? ? ? ? const float* v = sv.ptr<float>(i);

? ? ? ? // 6是圓的半徑脓魏,(128,128,128)是灰色

? ? ? ? circle(image, Point((int)v[0], (int)v[1]), 10, Scalar(128, 128, 128), thickness, lineType);

? ? }

? ? //! [show_vectors]

? ? imwrite("result.png", image);? ? ? ? // save the image

? ? imshow("SVM Simple Example", image); // show it to the user

? ? waitKey(0);

}


3.用SVM做簡單的圖像分割

直接看代碼兰吟,同樣做了注釋:

#include <opencv2/core.hpp>

#include <opencv2/imgproc.hpp>

#include "opencv2/imgcodecs.hpp"

#include <opencv2/highgui.hpp>

#include <opencv2/ml.hpp>

#include <iostream>

using namespace std;

using namespace cv;

using namespace cv::ml;

int main()

{

? ? Mat srcImg = imread("test.jpg");

? ? Mat desImg = srcImg.clone();

? ? imshow("原圖", srcImg);

? ? // 選取目標(biāo)區(qū)域和背景區(qū)域

? ? Mat BackImg = srcImg(Rect(199, 0, 30, 30));

? ? Mat ForeImg = srcImg(Rect(38, 95, 30, 30));

? ? // 初始化訓(xùn)練數(shù)據(jù)

? ? Mat trainingDataMat = ForeImg.clone().reshape(1, ForeImg.cols*ForeImg.rows);

? ? //在這里直接存入背景像素點,或者像下邊一個一個點存入也可以

? ? trainingDataMat.push_back(BackImg.clone().reshape(1,BackImg.cols*BackImg.rows));

? ? trainingDataMat.convertTo(trainingDataMat, CV_32FC1);

? ? // 初始化標(biāo)簽茂翔,分別給兩種標(biāo)簽輔助混蔼,雖然這里memset已經(jīng)全部初始化為1了,可是這里的1是浮點數(shù)

? ? int *labels = new int[ForeImg.cols*ForeImg.rows + BackImg.cols*BackImg.rows];

? ? memset(labels, 1, sizeof(int)*(ForeImg.cols*ForeImg.rows + BackImg.cols*BackImg.rows));

? ? for (int i = 0; i < ForeImg.rows; ++i)

? ? ? ? for (int j = 0; j < ForeImg.cols; ++j){

? ? ? ? ? ? labels[i*ForeImg.cols + j] = 1;

? ? ? ? }

? ? for (int h = 0; h<BackImg.rows; h++)

? ? {

? ? ? ? for (int w = 0; w<BackImg.cols; w++)

? ? ? ? {

? ? ? ? ? ? labels[ForeImg.cols*ForeImg.rows + h*BackImg.cols + w] = -1;

? ? ? ? }

? ? }

? ? Mat labelsMat = Mat(ForeImg.cols*ForeImg.rows + BackImg.cols*BackImg.rows, 1, CV_32SC1, labels);

? ? // 可以將數(shù)據(jù)寫入文件來檢查是否正確

? ? //FileStorage fs("data.xml", FileStorage::WRITE);

? ? //fs << "traindata" << trainingDataMat << "labels" << labelsMat;

? ? // Train the SVM

? ? Ptr<SVM> svm = SVM::create();

? ? svm->setType(SVM::C_SVC);

? ? svm->setKernel(SVM::RBF);

? ? svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, (int)1e5, 1e-6));

? ? svm->train(trainingDataMat, ROW_SAMPLE, labelsMat);

? ? // 開始分類

? ? Vec3b black(0, 0, 0), white(255, 255, 255);

? ? for (int i = 0; i < desImg.rows; ++i)

? ? {

? ? ? ? uchar* p_sample = desImg.ptr<uchar>(i);

? ? ? ? for (int j = 0; j < desImg.cols; ++j)

? ? ? ? {

? ? ? ? ? ? Mat sampleMat(1, 3, CV_32FC1);

? ? ? ? ? ? sampleMat.at<float>(0, 0) = p_sample[3 * j + 0];

? ? ? ? ? ? sampleMat.at<float>(0, 1) = p_sample[3 * j + 1];

? ? ? ? ? ? sampleMat.at<float>(0, 2) = p_sample[3 * j + 2];

? ? ? ? ? ? float response = svm->predict(sampleMat);

? ? ? ? ? ? if (response == 1)

? ? ? ? ? ? ? ? desImg.at<Vec3b>(i, j) = white;

? ? ? ? ? ? else if (response == -1)

? ? ? ? ? ? ? ? desImg.at<Vec3b>(i, j) = black;

? ? ? ? }

? ? }

? ? imwrite("result.jpg", desImg);

? ? imshow("resImg", desImg);

? ? waitKey(0);

? ? return 0;

}


這里的白塊就是我們選得目標(biāo)區(qū)域珊燎。不知道是不是我參數(shù)選擇不好惭嚣,這里的分割效果步理想。

參考博客:利用SVM支持向量機(jī)對彩色圖像進(jìn)行分割并使用OpenCV進(jìn)行實現(xiàn)

支持向量機(jī)通俗導(dǎo)論(理解SVM的三層境界)

---------------------

作者:影子要造反

來源:CSDN

原文:https://blog.csdn.net/shi923281339/article/details/77094757

版權(quán)聲明:本文為博主原創(chuàng)文章悔政,轉(zhuǎn)載請附上博文鏈接晚吞!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谋国,隨后出現(xiàn)的幾起案子槽地,更是在濱河造成了極大的恐慌,老刑警劉巖芦瘾,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捌蚊,死亡現(xiàn)場離奇詭異,居然都是意外死亡近弟,警方通過查閱死者的電腦和手機(jī)缅糟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來祷愉,“玉大人窗宦,你說我怎么就攤上這事《” “怎么了赴涵?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長订讼。 經(jīng)常有香客問我髓窜,道長,這世上最難降的妖魔是什么躯嫉? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任纱烘,我火速辦了婚禮,結(jié)果婚禮上祈餐,老公的妹妹穿的比我還像新娘擂啥。我一直安慰自己,他們只是感情好帆阳,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布哺壶。 她就那樣靜靜地躺著屋吨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪山宾。 梳的紋絲不亂的頭發(fā)上至扰,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機(jī)與錄音资锰,去河邊找鬼敢课。 笑死,一個胖子當(dāng)著我的面吹牛绷杜,可吹牛的內(nèi)容都是我干的直秆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼鞭盟,長吁一口氣:“原來是場噩夢啊……” “哼圾结!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起齿诉,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤筝野,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后粤剧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體歇竟,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年俊扳,在試婚紗的時候發(fā)現(xiàn)自己被綠了途蒋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猛遍。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡馋记,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出懊烤,到底是詐尸還是另有隱情梯醒,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布腌紧,位于F島的核電站茸习,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏壁肋。R本人自食惡果不足惜号胚,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浸遗。 院中可真熱鬧猫胁,春花似錦、人聲如沸跛锌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至菠赚,卻和暖如春脑豹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背衡查。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工瘩欺, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拌牲。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓击碗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親们拙。 傳聞我的和親對象是個殘疾皇子稍途,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容