gpt4 book ai didi

c++ - OpenCV:自定义区域/图像作为 GrabCut 的 "background"的来源

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:45:17 24 4
gpt4 key购买 nike

我有人类图像,我想在其中消除一些模式。请看下面的三张图片:

GrabCut 毫无问题地从第一张图片中提取了图形(第二张图片)。

现在我有一个与面部对应的矩形(第二张图片上的圆圈),我想将其用作“背景”(而图像的其余部分将是前景和背景的组合)以消除皮肤残留只有衣服。

大致想要的结果在第三张图上:

GrabCut stages

有什么办法可以让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

第二个 grabcut 调用也需要更多的迭代,大约 5-7 次迭代。

结果不是很好,欢迎能改进的答案。

results

关于c++ - OpenCV:自定义区域/图像作为 GrabCut 的 "background"的来源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40030621/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com