grabcut基於**"grabcut" - interactive foreground extraction using iterated graph cuts,是微軟亞洲研究院04年的**。
本**摘自opencv的示例**,自己做了一些修改,加入了乙個輸出mask的功能。另外,由於grabcut會造成不少小洞,所以還加入了了乙個輪廓檢測模組。但這樣會導致最外層的一層畫素顯示不出來。
detect.h:
//本程式的目的是檢測mask
//缺點: 1, 會造成邊界有乙個畫素丟失
//2, 會造成obj中間的洞檢測不出來
#include #include #include using namespace cv;
#include using namespace std;
int getmaxcontour(vector> contours)
else
return result; }}
mat getmask(mat mask, vec3b color)
grabcut.cpp:
//本程式的目的是測試grabcut演算法
#include #include #include using namespace cv;
#include using namespace std;
#include "detect.h"
static void help()
const scalar red = scalar(0,0,255);
const scalar pink = scalar(230,130,255);
const scalar blue = scalar(255,0,0);
const scalar lightblue = scalar(255,255,160);
const scalar green = scalar(0,255,0);
const int bgd_key = cv_event_flag_ctrlkey;
const int fgd_key = cv_event_flag_shiftkey;
mat finalmask;
static void getbinmask( const mat& commask, mat& binmask )
; static const int radius = 2;
static const int thickness = -1;
void reset();
void setimageandwinname( const mat& _image, const string& _winname );
void showimage() const;
void write();
void mouseclick( int event, int x, int y, int flags, void* param );
int nextiter();
int getitercount() const
private:
void setrectinmask();
void setlblsinmask( int flags, point p, bool ispr );
const string* winname;
const mat* image;
mat mask;
mat bgdmodel, fgdmodel;
uchar rectstate, lblsstate, prlblsstate;
bool isinitialized;
rect rect;
vectorfgdpxls, bgdpxls, prfgdpxls, prbgdpxls;
int itercount;
}; vector::const_iterator it;
for( it = bgdpxls.begin(); it != bgdpxls.end(); ++it )
circle( res, *it, radius, blue, thickness );
for( it = fgdpxls.begin(); it != fgdpxls.end(); ++it )
circle( res, *it, radius, red, thickness );
for( it = prbgdpxls.begin(); it != prbgdpxls.end(); ++it )
circle( res, *it, radius, lightblue, thickness );
for( it = prfgdpxls.begin(); it != prfgdpxls.end(); ++it )
circle( res, *it, radius, pink, thickness );
if( rectstate == in_process || rectstate == set )
rectangle( res, point( rect.x, rect.y ), point(rect.x + rect.width, rect.y + rect.height ), green, 2);
imshow( *winname, res );
} else
if( flags & bgd_key )
if( flags & fgd_key ) }
if ( (isb || isf) && rectstate == set )
lblsstate = in_process;
} break;
case cv_event_rbuttondown: // set gc_pr_bgd(gc_pr_fgd) labels
break;
case cv_event_lbuttonup:
if( rectstate == in_process )
if( lblsstate == in_process )
break;
case cv_event_rbuttonup:
if( prlblsstate == in_process )
break;
case cv_event_mousemove:
if( rectstate == in_process )
else if( lblsstate == in_process )
else if( prlblsstate == in_process )
break; }}
itercount++;
bgdpxls.clear(); fgdpxls.clear();
prbgdpxls.clear(); prfgdpxls.clear();
return itercount;
}static void on_mouse( int event, int x, int y, int flags, void* param )
int main( int argc, char** argv )
mat image = imread( filename, 1 );
if( image.empty() )
help();
mat src = image.clone();
imshow("src", src);
finalmask = mat::zeros(src.size(), cv_8uc3);
const string winname = "image";
cvnamedwindow( winname.c_str(), cv_window_autosize );
cvsetmousecallback( winname.c_str(), on_mouse, 0 );
for(;;)
case 'r':
case 'n':
else
cout << "rect must be determined>" << endl;
break;
}case 'w':
}}exit_main:
}
最後,opencv的效果和原文有一定差距。這是因為原文加入了border matting的技術,而因為專利權的原因,opencv沒有加。
opencv GrabCut前景檢測
grabcut函式原型 def grabcut img,mask,rect,bgdmodel,fgdmodel,itercount,mode none img為原影象,mask為掩模,bgdmodel為前景背景模型,fgdmodel為後景背景模型,rect為初始矩形,背景和前景模型都要基於這個矩形所...
python檔案分割,列表分割
python分割檔案或列表作為多執行緒,多程序輸入 path為檔案路徑,n每個分割塊的大小 import pandas as pd def split file path,n df pd.read table path,iterator true loop true chunks while loo...
語義分割 例項分割 全景分割的關係和區別
這三者的區別請參考超畫素 語義分割 例項分割 全景分割 傻傻分不清?簡單來說 1.語義分割是最簡單的,對每個畫素做分類,比如說將這幅影象分為人和汽車。但是具體有三個人,無法對這三個人做具體區分。注意是每乙個畫素點,不分前景 背景。2.例項分割是在語義分割的基礎上,對這三個人做具體區分,分出甲 乙 丙...