opencv grabcut 分割演算法

2021-06-20 08:16:52 字數 4115 閱讀 2700

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.例項分割是在語義分割的基礎上,對這三個人做具體區分,分出甲 乙 丙...