OpenCV中Grabcut算法的具體使用
Grabcut 算法主要運(yùn)用于計(jì)算機(jī)視覺中的前背景分割,立體視覺和摳圖等。該算法利用了圖像中的紋理(顏色)信息和邊界(反差)信息,只要少量的用戶交互操作即可得到比較好的分割結(jié)果.
1. Grabcut 的目標(biāo)和背景的模型是RGB三通道的混合高斯模型GMM;
2. Grab Cut為一個(gè)不斷進(jìn)行分割估計(jì)和模型參數(shù)學(xué)習(xí)的交互迭代過程;
3. Grab Cut只需要提供背景區(qū)域的像素集就可以了。也就是說你只需要框選目標(biāo),那么在方框外的像素全部當(dāng)成背景,這時(shí)候就可以對(duì)GMM進(jìn)行建模和完成良好的分割了。即Grab Cut允許不完全的標(biāo)注.
Grabcut 算法的基本步驟:
Grabcut的相關(guān)API:
void grabCut( InputArray img, //輸入圖像,必須是8位3通道圖像,在處理過程中不會(huì)被修改 InputOutputArray mask, //掩碼圖像,用來確定哪些區(qū)域是背景,前景,可能是背景, 可能是前景等 //mask既可以作為輸入也可以作為輸出。作為輸入時(shí),mode要 選擇GC_INIT_WITH_MASK (=1); GCD_BGD (=0), 背景;GCD_FGD (=1),前景;GCD_PR_BGD (=2),可能是背景;GCD_PR_FGD(=3),可能是前景 Rect rect, //包含前景的矩形,格式為(x, y, w, h) InputOutputArray bgdModel,//算法內(nèi)部使用的數(shù)組,只需要?jiǎng)?chuàng)建大小為(1,65), 數(shù)據(jù)類型為np.float64的數(shù)組 InputOutputArray fgdModel,//同上 int iterCount, //算法迭代的次數(shù) int mode = GC_EVAL //用來指示grabCut函數(shù)進(jìn)行什么操作 // GC_INIT_WITH_RECT (=0),用矩形窗初始化GrabCut; // GC_INIT_WITH_MASK (=1),用掩碼圖像初始化GrabCut );
有關(guān)鼠標(biāo)操作的兩個(gè)函數(shù):
void setMouseCallback( const string& winname, //圖像視窗名稱 MouseCallback onMouse, //鼠標(biāo)響應(yīng)函數(shù),監(jiān)視到鼠標(biāo)操作后調(diào)用并處理相 應(yīng)動(dòng)作 void* userdata = 0 //鼠標(biāo)響應(yīng)處理函數(shù)的ID,識(shí)別號(hào) );
void OnMouseAction( int event, // 代表了鼠標(biāo)的各種操作 int x, // 代表鼠標(biāo)位于窗口的(x,y)坐標(biāo)位置,即Point(x,y) int y, int flags, // 代表鼠標(biāo)的拖拽事件,以及鍵盤鼠標(biāo)聯(lián)合事件 void *ustc // 標(biāo)識(shí)了所響應(yīng)的事件函數(shù) );
int event: #define CV_EVENT_MOUSEMOVE 0 //滑動(dòng) #define CV_EVENT_LBUTTONDOWN 1 //左鍵點(diǎn)擊 #define CV_EVENT_RBUTTONDOWN 2 //右鍵點(diǎn)擊 #define CV_EVENT_MBUTTONDOWN 3 //中鍵點(diǎn)擊 #define CV_EVENT_LBUTTONUP 4 //左鍵放開 #define CV_EVENT_RBUTTONUP 5 //右鍵放開 #define CV_EVENT_MBUTTONUP 6 //中鍵放開 #define CV_EVENT_LBUTTONDBLCLK 7 //左鍵雙擊 #define CV_EVENT_RBUTTONDBLCLK 8 //右鍵雙擊 #define CV_EVENT_MBUTTONDBLCLK 9 //中鍵雙擊
int flags: #define CV_EVENT_FLAG_LBUTTON 1 //左鍵拖曳 #define CV_EVENT_FLAG_RBUTTON 2 //右鍵拖曳 #define CV_EVENT_FLAG_MBUTTON 4 //中鍵拖曳 #define CV_EVENT_FLAG_CTRLKEY 8 //(8~15)按Ctrl不放事件 #define CV_EVENT_FLAG_SHIFTKEY 16 //(16~31)按Shift不放事件 #define CV_EVENT_FLAG_ALTKEY 32 //(32~39)按Alt不放事件
Grabcut 算法的代碼示例:
#include<opencv2\highgui\highgui.hpp> #include<opencv2\imgproc\imgproc.hpp> #include<iostream> #include <opencv2\opencv.hpp> #include <math.h> using namespace cv; using namespace std; //grabcut算法 bool setMouse = false; //判斷鼠標(biāo)左鍵的狀態(tài)(up / down) bool init; Point pt; Rect rect; Mat srcImg, mask, bgModel, fgModel; int numRun = 0; void onMouse(int, int, int, int, void*); void runGrabCut(); void showImage(); int main() { srcImg = imread("tahiti.jpg"); if (srcImg.empty()) { printf("could not load image...\n"); return -1; } imshow("源圖像", srcImg); mask.create(srcImg.size(), CV_8U); setMouseCallback("源圖像", onMouse, 0); while (1) { char c = (char)waitKey(0); if (c == ' ') {//選中矩形框后,按空格鍵執(zhí)行g(shù)rabcut分割 runGrabCut(); numRun++; showImage(); printf("current iteative times : %d\n", numRun); } if ((int)c == 27) { break; } } return 0; } void showImage() { Mat result, binmask; binmask = mask & 1; //進(jìn)一步掩膜 if (init) //進(jìn)一步摳出無效區(qū)域。鼠標(biāo)按下,init變?yōu)閒alse { srcImg.copyTo(result, binmask); } else { result = srcImg.clone(); } rectangle(result, rect, Scalar(0, 0, 255), 2, 8); imshow("源圖像", result); } void onMouse(int events, int x, int y, int flag, void *) { if (x < 0 || y < 0 || x > srcImg.cols || y > srcImg.rows) //無效區(qū)域 return; if (events == EVENT_LBUTTONDOWN) { setMouse = true; pt.x = x; pt.y = y; init = false; } else if (events == EVENT_MOUSEMOVE)//鼠標(biāo)只要?jiǎng)?,就?zhí)行一次 { if (setMouse == true) //鼠標(biāo)左鍵按住,滑動(dòng) { Point pt1; pt1.x = x; pt1.y = y; rect = Rect(pt, pt1);//定義矩形區(qū)域 showImage(); mask.setTo(Scalar::all(GC_BGD));//背景 mask(rect).setTo(Scalar(GC_PR_FGD));//前景 //對(duì)rect內(nèi)部設(shè)置為可能的前景,外部設(shè)置為背景 } } else if (events == EVENT_LBUTTONUP) setMouse = false; //鼠標(biāo)左鍵抬起 } void runGrabCut() { if (init)//鼠標(biāo)按下,init變?yōu)閒alse grabCut(srcImg, mask, rect, bgModel, fgModel, 1);//第二次迭代,用mask初始化grabcut else { grabCut(srcImg, mask, rect, bgModel, fgModel, 1, GC_INIT_WITH_RECT);//用矩形窗初始化GrabCut init = true; } }
到此這篇關(guān)于OpenCV中Grabcut算法的具體使用的文章就介紹到這了,更多相關(guān)OpenCV Grabcut算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++20 特性 協(xié)程 Coroutines(1)
這篇文章主要給大家分享得是C++20 得特性 協(xié)程 Coroutines,下面文章內(nèi)容我們將來具體介紹什么是協(xié)程,協(xié)程得好處等知識(shí)點(diǎn),需要的朋友可以參考一下2021-10-10深入剖析C++中的struct結(jié)構(gòu)體字節(jié)對(duì)齊
要求數(shù)據(jù)內(nèi)存的起始地址的值是某個(gè)數(shù)k的倍數(shù),這就是所謂的內(nèi)存對(duì)齊,本文就來深入剖析C++中的struct結(jié)構(gòu)體字節(jié)對(duì)齊,需要的朋友可以參考下2016-05-05方陣順時(shí)針旋轉(zhuǎn)的實(shí)現(xiàn)代碼
以下是關(guān)于方陣順時(shí)針旋轉(zhuǎn)的實(shí)現(xiàn)代碼。需要的朋友參考下2013-05-05C++ opencv實(shí)現(xiàn)車道線識(shí)別
這篇文章主要為大家詳細(xì)介紹了C++ opencv實(shí)現(xiàn)車道線識(shí)別,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-02-02使用OpenGL實(shí)現(xiàn)3D立體顯示的程序代碼
本篇文章是對(duì)使用OpenGL實(shí)現(xiàn)3D立體顯示的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05使用C++實(shí)現(xiàn)給PDF文檔添加文字水印
這篇文章主要為大家詳細(xì)介紹了如何通過第三方國產(chǎn)庫Spire.PDF?for?C++來實(shí)現(xiàn)給PDF文檔添加文字水印,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-11-11