C++ 利用grabbut提取背景图像
我有一个图像(.jpg图像),我想从原始图像中提取背景。我在谷歌上搜索了很多,但只找到了提取前景图像的教程 我从另一个人那里得到了密码。代码对我来说很好,我已经成功地提取了前景(根据我的要求)。现在我想从原始图像中完全删除这个前景。我希望它是这样的:- 背景=原始图像-前景 空白区域可以用黑色或白色填充。我怎样才能做到这一点 我尝试过使用这种技术:-C++ 利用grabbut提取背景图像,c++,opencv,C++,Opencv,我有一个图像(.jpg图像),我想从原始图像中提取背景。我在谷歌上搜索了很多,但只找到了提取前景图像的教程 我从另一个人那里得到了密码。代码对我来说很好,我已经成功地提取了前景(根据我的要求)。现在我想从原始图像中完全删除这个前景。我希望它是这样的:- 背景=原始图像-前景 空白区域可以用黑色或白色填充。我怎样才能做到这一点 我尝试过使用这种技术:- Mat background = image2 - foreground; 但它给出了一个完整的黑色图像 代码:- #include <o
Mat background = image2 - foreground;
但它给出了一个完整的黑色图像
代码:-
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( )
{
// Open another image
Mat image;
image= cv::imread("images/abc.jpg");
Mat image2 = image.clone();
// define bounding rectangle
cv::Rect rectangle(40,90,image.cols-80,image.rows-170);
cv::Mat result; // segmentation result (4 possible values)
cv::Mat bgModel,fgModel; // the models (internally used)
// GrabCut segmentation
cv::grabCut(image, // input image
result, // segmentation result
rectangle,// rectangle containing foreground
bgModel,fgModel, // models
1, // number of iterations
cv::GC_INIT_WITH_RECT); // use rectangle
cout << "oks pa dito" <<endl;
// Get the pixels marked as likely foreground
cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
// Generate output image
cv::Mat foreground(image.size(),CV_8UC3,cv::Scalar(255,255,255));
//cv::Mat background(image.size(),CV_8UC3,cv::Scalar(255,255,255));
image.copyTo(foreground,result); // bg pixels not copied
// draw rectangle on original image
cv::rectangle(image, rectangle, cv::Scalar(255,255,255),1);
imwrite("img_1.jpg",image);
imwrite("Foreground.jpg",foreground);
Mat background = image2 - foreground;
imwrite("Background.jpg",background);
return 0;
}
#包括
#包括
使用名称空间cv;
使用名称空间std;
int main()
{
//打开另一个图像
Mat图像;
image=cv::imread(“images/abc.jpg”);
Mat image2=image.clone();
//定义边框
矩形(40,90,image.cols-80,image.rows-170);
cv::Mat result;//分段结果(4个可能值)
cv::Mat bgModel,fgModel;//模型(内部使用)
//地堑分割
cv::grabCut(图像,//输入图像
result,//分割结果
矩形,//包含前景的矩形
bgModel,fgModel,//模型
1,//迭代次数
cv::GC_INIT_WITH_RECT);//使用矩形
cout它不复制所有前景像素,而是复制所有非前景像素。您可以使用~
来执行此操作,这会使遮罩无效:
image.copyTo(background,~result);
如果您//将像素标记为可能的背景会怎么样
// Get the pixels marked as likely background
cv::compare(result,cv::GC_PR_BGD,result,cv::CMP_EQ);
编辑:上面的代码缺少GC\U BGD像素。尽管给出了更有效的答案,让我们完成开始的部分:
// Get the pixels marked as background
cv::compare(result,cv::GC_BGD,result_a,cv::CMP_EQ);
// Get the pixels marked as likely background
cv::compare(result,cv::GC_PR_BGD,result_b,cv::CMP_EQ);
// Final results
result=result_a+result_b;
只是一个小小的建议
答案可以更简洁地写为:
result = result & 1;
为了得到二值遮罩。也许另一个例子会有所帮助,在这个例子中,我假设图像的中间部分肯定是前景。
所以试试这个链接。
你搞定了。谢谢:-)是的,它删除了前景,但也将图像裁剪到了我指定的矩形。谢谢你的回答。问题是,有些像素被标记为GC\u PR\u BGD
(可能是背景)还有一些是GC_BGD
,这意味着它们肯定是背景,因为它们是作为算法的输入提供的。是的。我们需要保留这两个,这意味着可能还有一行代码。