1. 程式人生 > >前景提取、去除背景(selectROI+Grabcut)

前景提取、去除背景(selectROI+Grabcut)

前幾天看到別人數學建模題目是前景提取,想到很早之前試過的grabcut,所以來放個demo,2333

慣例先放效果   //必須是三通道圖片

兩個函式:

1.selectROI 【需要配置Opencv的contribute模組】、、主要作用是獲取矩形框,可自行寫其他

第一個引數為輸入圖片,第二個引數為是否從中心開始選取矩形

2.grabCut函式 //輸入必須是三通道的彩色圖

詳細用法如下:

/*
	參考:
	http://blog.csdn.net/zouxy09/article/details/8535087
	****引數說明:

	image——待分割的源影象,必須是8位3通道(CV_8UC3)影象,在處理的過程中不會被修改;

	mask——掩碼影象,如果使用掩碼進行初始化,那麼mask儲存初始化掩碼資訊;在執行分割的時候,也可以將使用者互動所設定的前景與背景儲存到mask中,然後再傳入grabCut函式;在處理結束之後,mask中會儲存結果。mask只能取以下四種值:

	GCD_BGD(=0),背景;

	GCD_FGD(=1),前景;

	GCD_PR_BGD(=2),可能的背景;

	GCD_PR_FGD(=3),可能的前景。

	如果沒有手工標記GCD_BGD或者GCD_FGD,那麼結果只會有GCD_PR_BGD或GCD_PR_FGD;

	rect——用於限定需要進行分割的影象範圍,只有該矩形視窗內的影象部分才被處理;

	bgdModel——背景模型,如果為null,函式內部會自動建立一個bgdModel;bgdModel必須是單通道浮點型(CV_32FC1)影象,且行數只能為1,列數只能為13x5;

	fgdModel——前景模型,如果為null,函式內部會自動建立一個fgdModel;fgdModel必須是單通道浮點型(CV_32FC1)影象,且行數只能為1,列數只能為13x5;

	iterCount——迭代次數,必須大於0;

	mode——用於指示grabCut函式進行什麼操作,可選的值有:

	GC_INIT_WITH_RECT(=0),用矩形窗初始化GrabCut;

	GC_INIT_WITH_MASK(=1),用掩碼影象初始化GrabCut;

	GC_EVAL(=2),執行分割。

	*/


下面就是簡單粗暴的程式碼了,233

//Interactive Foreground Extraction using Iterated Graph Cuts


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

using namespace std;
using namespace cv;

int main()
{
	Mat image = imread("test.jpg");
	Mat mask; 

	//框選前景所在區域
	bool fromCenter = false;
	Rect2d r = selectROI(image,fromCenter);

	Mat bgModel, fgModel; // 模型(內部使用)  
	grabCut(image,mask, r, bgModel, fgModel, 1, cv::GC_INIT_WITH_RECT);
	


	// 得到可能為前景的畫素  
	compare(mask, cv::GC_PR_FGD, mask, cv::CMP_EQ);
	imshow("mask", mask);
	// 生成輸出影象  
	Mat foreground(image.size(), CV_8UC3, cv::Scalar(255, 255, 255));
	image.copyTo(foreground, mask); // 複製背景資料  

	// 輸出前景影象結果  
	cv::imshow("提取後", foreground);


	cvWaitKey(0); //等待退出  
	return 0;
}


//口腔潰瘍好嚴重,我去多吃點草了……