opencv-使用GrabCut提取背景图像

参考:
1、https://stackoverflow.com/questions/17698431/extracting-background-image-using-grabcut
2、https://stackoverflow.com/questions/15536222/opencv-grabcut-algorithm-example-not-working


1、提取前景图像

c++

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int main( )
{
 // Open another image
    Mat image;
    image= cv::imread("images/mango11a.jpg");

    // define bounding rectangle 
    cv::Rect rectangle(50,70,image.cols-150,image.rows-180);

    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));
    image.copyTo(foreground,result); // bg pixels not copied

    // draw rectangle on original image
    cv::rectangle(image, rectangle, cv::Scalar(255,255,255),1);
    cv::namedWindow("Image");
    cv::imshow("Image",image);

    // display result
    cv::namedWindow("Segmented Image");
    cv::imshow("Segmented Image",foreground);


    waitKey();
    return 0;
}

python

# -*- coding: UTF-8 -*-

import cv2
import numpy as np

image=cv2.imread("messi5.jpg")

# define bounding rectangle
rectangle = (50,70,image.shape[1]-100,image.shape[0]-200)

result = np.zeros(image.shape[:2],np.uint8)

# bgdModel = np.zeros((1,65),np.float64)
# fgdModel = np.zeros((1,65),np.float64)
bgdModel = None
fgdModel = None
# GrabCut segmentation
cv2.grabCut(image,result,rectangle,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)

# """
# Get the pixels marked as likely foreground
result=cv2.compare(result,cv2.GC_PR_FGD,cv2.CMP_EQ) # 获取前景像素值  GC_PR_BGD 背景像素值

# Generate output image
mask=np.zeros(image.shape,np.uint8)
mask[:,:,0]=result
mask[:,:,1]=result
mask[:,:,2]=result
foreground=cv2.bitwise_and(image,mask)
# """

# 或
mask= np.where((result==2)|(result==0),0,1).astype('uint8')
foreground = image*mask[:,:,np.newaxis]


# draw rectangle on original image
cv2.rectangle(image,rectangle[:2],rectangle[2:],(255,255,255),1)
cv2.namedWindow("Image",0)
cv2.imshow("Image",image)

# display result
cv2.namedWindow("Segmented Image",0)
cv2.imshow("Segmented Image",foreground)

cv2.waitKey(0)
cv2.destroyAllWindows()

2、提取背景颜色

python

# -*- coding: UTF-8 -*-

import cv2
import numpy as np

image=cv2.imread("messi5.jpg")

# define bounding rectangle
rectangle = (50,70,image.shape[1]-100,image.shape[0]-200)

result = np.zeros(image.shape[:2],np.uint8)

# bgdModel = np.zeros((1,65),np.float64)
# fgdModel = np.zeros((1,65),np.float64)
bgdModel = None
fgdModel = None
# GrabCut segmentation
cv2.grabCut(image,result,rectangle,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)


# Get the pixels marked as likely foreground
result=cv2.compare(result,cv2.GC_PR_BGD,cv2.CMP_EQ) # GC_PR_BGD 背景像素值

# Generate output image

_,result=cv2.threshold(result,128,255,cv2.THRESH_BINARY)
mask=np.zeros(image.shape,np.uint8)
mask[:,:,0]=result
mask[:,:,1]=result
mask[:,:,2]=result
background=cv2.bitwise_and(image,mask)


# draw rectangle on original image
cv2.rectangle(image,rectangle[:2],rectangle[2:],(255,255,255),1)
cv2.namedWindow("Image",0)
cv2.imshow("Image",image)

# display result
cv2.namedWindow("Segmented Image",0)
cv2.imshow("Segmented Image",background)

cv2.waitKey(0)
cv2.destroyAllWindows()

C++

#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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值