[英]OpenCV: custom area/image as a source of a “background” for GrabCut
我有要消除某些模式的人像。 請看下面的三個圖像:
GrabCut從第一張圖像中提取了圖形(第二張圖片),沒有任何問題。
現在我有一個與臉部相對應的矩形(第二張圖片上的圓圈),我想將其用作“背景”(而圖像的其余部分將是前景和背景的組合),以消除僅衣服留下的皮膚。
大致所需的結果在第三張圖片上:
有什么辦法可以使GrabCut做到這一點? 我無法手動分配區域/遮罩,我所擁有的只是人臉檢測提供的矩形。
UPD:在下面的代碼中,我嘗試使用遮罩進行處理, 但是第2階段似乎不起作用(因為至少應該剪掉面部)。 也許我只是不了解它是如何工作的,因為我剛剛修改了另一個示例代碼正在工作:
static Mat my_segment(Mat _inImage, Rect assumption, Rect face){
// human segmentation opencv
// _inImage - input image
// assumption - human rectangle on _inImage
// face - face rectangle on _inImage
// iterations - is being set externally
/*
GrabCut segmentation
*/
Mat bgModel,fgModel; // the models (internally used)
Mat result; // segmentation result
//*********************** step1: GrabCut human figure segmentation
grabCut(_inImage, // input image
result, // segmentation result
assumption,// rectangle containing foreground
bgModel,fgModel, // models
iterations, // number of iterations
cv::GC_INIT_WITH_RECT); // use rectangle
// Get the pixels marked as likely foreground
cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
// upsample the resulting mask
cv::Mat separated(assumption.size(),CV_8UC3,cv::Scalar(255,255,255));
_inImage(assumption).copyTo(separated,result(assumption));
// (bg pixels not copied)
//return(separated); // return the innerings of assumption rectangle
//*********************** step2:
//cutting the skin with the mask based on the face rectangle
Rect adjusted_face = face;
adjusted_face.x = face.x - assumption.x;
adjusted_face.y = face.y - assumption.y;
//rectangle(separated,
// adjusted_face.tl(),
// adjusted_face.br(),
// cv::Scalar(166,94,91), 2);
//creating mask
Mat mymask(separated.size(),CV_8UC1);
// setting face area as sure background
mymask.setTo(Scalar::all(GC_PR_FGD));
mymask(adjusted_face).setTo(Scalar::all(GC_BGD));
// performing grabcut
grabCut(separated,
mymask,
cv::Rect(0,0,assumption.width,assumption.height),
bgModel,fgModel,
1,
cv::GC_INIT_WITH_MASK);
// Just repeating everything from before
// Get the pixels marked as likely foreground
cv::compare(mymask,cv::GC_PR_FGD,mymask,cv::CMP_EQ);
//here was the error
//separated.copyTo(separated,mymask); // bg pixels not copied
cv::Mat res(separated.size(),CV_8UC3,cv::Scalar(255,255,255));
separated.copyTo(res,mymask); // bg pixels not copied
//*************************//
//return(separated); // return the innerings of assumption rectangle
return(res);
}
好吧,我發現了錯誤,而不是
separated.copyTo(separated,mymask);
最后幾行應更改為:
cv::Mat res(separated.size(),CV_8UC3,cv::Scalar(255,255,255));
separated.copyTo(res,mymask); // bg pixels not copied
//*************************//
return(res); // return the innerings of assumption rectangle
同樣,第二次抓取調用需要更多的迭代次數,例如5-7迭代次數。
結果不是很好,所以我歡迎可以改善它的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.