使用 GrabCut 提取背景图像
Extracting Background Image Using GrabCut
我有一张图像(.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;
}
注意:我是一个opencv初学者,现在对它没有太多了解。如果您可以发布完整的代码(根据我的要求(或只是发布代码行并告诉我这些代码行的位置,我将非常感谢您。谢谢。
附言这是我 StackOverflow.com 的第二个问题。道歉。。。如果不遵循任何惯例。
它不是复制所有前景像素,而是复制所有非前景像素。您可以使用 ~
来执行此操作,这会否定掩码:
image.copyTo(background,~result);
如果你//Get the pixels marked as likely background
:
// Get the pixels marked as likely background
cv::compare(result,cv::GC_PR_BGD,result,cv::CMP_EQ);
编辑:上面的代码缺少GC_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;
只是一个小建议,@William的答案可以写得更简洁:
result = result & 1;
为了获得二进制掩码。
也许另一个例子会有所帮助,其中我假设图像的中间部分肯定是前景。所以试试这个链接。例
相关文章:
- 在 Visual C++ 中以编程方式更改按钮的背景图像
- 如何设置与其背景图像大小相对应的窗口大小?
- 同一图像中的反转文本和背景颜色
- 如何在QT中设置样式表以选择假发背景的随机图像
- 具有SPI_SETDESKWALLPAPER功能的程序仅在尝试使用C++将其更改为图像时将桌面背景更改为黑色
- 无法将图像保存在具有白色背景的JPG中 OpenCV
- QDialog - 设置背景图像
- 在 qlabel 中将图像设置为背景并在其顶部设置文本
- 为背景图像设置比例
- 将图像设置为Drawingarea的背景
- 为qlineedit设置了背景图像时,如何在qlineedit中设置文本颜色
- 打开不同的图像文件,并使用GDI 库在主应用程序窗口的背景上绘制它们
- 如何让 WNDCLASS 将位图图像作为背景
- 直接X背景图像
- 在 MFC 窗口中使用 PNG 作为背景图像
- 有没有一种算法可以使用opencv来分离图像的前景和背景
- 在屏幕上绘制图像后背景发生变化
- QPushButton的Qt背景图像
- 黑色背景,图像在中心使用 GDI
- 使用C++/OpenCV或Matlab将图像的白色背景替换为透明背景