概述
????圖片編輯中常需要用到摳圖功能,將圖片想要的部分扣出來(lái)再合成到別的圖中。本片文章主要介紹一種通過(guò)手指選取摳圖前景進(jìn)行摳圖的方案,主要利用OpenCV 的grabCut分割算法進(jìn)行摳圖。
摳圖原理:
1.bitmap轉(zhuǎn)mat。
2.采集mask,用戶選擇摳圖區(qū)域時(shí),記錄point 加入list中。
3.Imgproc.grabCut 傳入mask進(jìn)行摳圖,得到摳出部分并做邊緣處理。
4.mat轉(zhuǎn)bitmap,得到最終摳出的bitmap。
流程:
????????按比例放縮圖片--> 采集mask --> grabCut --> 邊緣處理 -->? 得到摳出的圖片grabcutBitmap --> grabcutBitmap轉(zhuǎn)化為純色colorBitimap -->colorBitimap放縮到原始大小,用于顯示最終扣出的圖片區(qū)域。(原圖按比例放縮到目標(biāo)尺寸,因?yàn)閛pencv 圖片越大摳圖時(shí)間越長(zhǎng),需要適當(dāng)縮小圖片,最終摳圖耗時(shí)600毫秒左右)
1.選擇一張圖片

2.選取需要摳出的部分,這里我想摳這只狗子,只需要手指涂抹這只狗子,如圖,只需要選中大致區(qū)域就可以,需要注意的是,這只狗通體白色,如果只選中白色區(qū)域,最后摳出來(lái)的圖,就會(huì)缺少眼睛和鼻子部分,所以需要把眼睛和鼻子的部分也選中。我們需要記錄手指滑動(dòng)經(jīng)過(guò)過(guò)位置的point,放入一個(gè)list。

3.摳圖
3.1 Bitmap 轉(zhuǎn)Mat
Mat?imgPR =new Mat();
Utils.bitmapToMat(mScaleBitmap, imgPR);
3.2 收集mask,手指移動(dòng)是,將point 傳給firstMask
Mat?firstMask =new Mat();
Size size =new Size(mScaleBitmap.getWidth(), mScaleBitmap.getHeight());
firstMask.create(size, CvType.CV_8UC1);
firstMask.setTo(new Scalar(GC_PR_BGD));//扣前景
for (int j =0; j < points.size(); j++) {
final Point point = points.get(j);
Imgproc.circle(firstMask, mPoint, radiusCircle, new Scalar(GC_FGD)); (mPoint就是觸摸的點(diǎn))}
3.4執(zhí)行g(shù)rabCut 方法
grabCut(Mat img, Mat mask, Rect rect, Mat bgdModel, Mat fgdModel, int iterCount, int mode)
img:輸入圖像,輸入圖像越小識(shí)別越快
mask: 選取的前景mask
rect: 包含前景的矩形
bgModel,fgModel : 前景、背景
iterCount: 迭代次數(shù) 次數(shù)越多識(shí)別越精確,但耗時(shí)更長(zhǎng)

3.5 最終識(shí)別的區(qū)域,如下圖,最終識(shí)別的區(qū)域就是這些,還是比較準(zhǔn)確的。

3.6 算法原理
在圖片中定義(一個(gè)或者多個(gè))包含物體的矩形。
矩形外的區(qū)域被自動(dòng)認(rèn)為是背景。
對(duì)于用戶定義的矩形區(qū)域,可用背景中的數(shù)據(jù)來(lái)區(qū)分它里面的前景和背景區(qū)域。
用高斯混合模型(GMM)來(lái)對(duì)背景和前景建模,并將未定義的像素標(biāo)記為可能的前景或者背景。
圖像中的每一個(gè)像素都被看做通過(guò)虛擬邊與周圍像素相連接,而每條邊都有一個(gè)屬于前景或者背景的概率,這是基于它與周邊像素顏色上的相似性。
每一個(gè)像素(即算法中的節(jié)點(diǎn))會(huì)與一個(gè)前景或背景節(jié)點(diǎn)連接。
在節(jié)點(diǎn)完成連接后(可能與背景或前景連接),若節(jié)點(diǎn)之間的邊屬于不同終端(即一個(gè)節(jié)點(diǎn)屬于前景,另一個(gè)節(jié)點(diǎn)屬于背景),則會(huì)切斷他們之間的邊,這就能將圖像各部分分割出來(lái)
ps:當(dāng)前景與背景像素顏色接近時(shí),識(shí)別不精準(zhǔn),選取mask時(shí) 盡量包含前景矩形區(qū)域內(nèi)所有顏色。