Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 利用grabbut提取背景图像_C++_Opencv - Fatal编程技术网

C++ 利用grabbut提取背景图像

C++ 利用grabbut提取背景图像,c++,opencv,C++,Opencv,我有一个图像(.jpg图像),我想从原始图像中提取背景。我在谷歌上搜索了很多,但只找到了提取前景图像的教程 我从另一个人那里得到了密码。代码对我来说很好,我已经成功地提取了前景(根据我的要求)。现在我想从原始图像中完全删除这个前景。我希望它是这样的:- 背景=原始图像-前景 空白区域可以用黑色或白色填充。我怎样才能做到这一点 我尝试过使用这种技术:- Mat background = image2 - foreground; 但它给出了一个完整的黑色图像 代码:- #include <o

我有一个图像(.jpg图像),我想从原始图像中提取背景。我在谷歌上搜索了很多,但只找到了提取前景图像的教程

我从另一个人那里得到了密码。代码对我来说很好,我已经成功地提取了前景(根据我的要求)。现在我想从原始图像中完全删除这个前景。我希望它是这样的:-

背景=原始图像-前景

空白区域可以用黑色或白色填充。我怎样才能做到这一点

我尝试过使用这种技术:-

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
,这意味着它们肯定是背景,因为它们是作为算法的输入提供的。是的。我们需要保留这两个,这意味着可能还有一行代码。