2014-01-27 150 views
0

對不起,請稍等解釋。作爲Open的新手,希望通過例子提供更多細節。在C++中使用OpenCV移除背景

我的要求是找到2個靜態圖像三角洲,這個現在用以下方法:

cv::Mat prevImg = cv::imread("prev.bmp"); 

cv::Mat currImg = cv::imread("curr.bmp"); 

cv::Mat deltaImg; 
cv::absdiff(prevImg,currImg,deltaImg); 

cv::namedWindow("image", CV_WINDOW_NORMAL); 

cv::absdiff(prevImg,currImg,deltaImg); 

cv::imshow("image", deltaImg); 

而在deltaImg,我得到的圖像之間的差異,但它包含了第一張圖片的背景也。我知道我必須使用BackgroundSubtractorMOG2刪除背景,但我無法理解此類的用法,因爲大多數示例均基於webcamera捕獲。

請注意我的圖像是靜態的(桌面活動的屏幕截圖)。

請指導我解決這個問題,一些示例代碼會有幫助。

注意我想計算RGB中的增量。

詳細Explination:

圖像處於:https://picasaweb.google.com/105653560142316168741/OpenCV?authkey=Gv1sRgCLesjvLEjNXzZg#

Prev.bmp:我dektop的一屏幕截圖

curr.bmp:我的臺式機的當前屏幕截圖

在prev.bmp和curr.bmp間的增量,應該是啓動菜單的圖像而已,請看下面的圖片:

增量圖像應該只包含啓動菜單,但是甚至包含prev.bmp的背景圖像,我想刪除此背景。

在此先感謝。

+0

如何定義「delta」?哪裏有一些例子?你有沒有讀過關於這方面的視覺理論? – scap3y

+0

嗨scap3y,編輯更多的細節和圖像鏈接,請檢查...謝謝 – user3239282

+0

上傳兩個工作截圖(**相同的大小和相同的位置**和bmp/png而不是JPG)將是非常好的...現在我只能告訴你我會做什麼(而不是發佈測試代碼):添加一個'cv :: Mat掩碼= deltaImg> 0; currImg.copyTo(deltaImg,mask);'應該工作。 – Micka

回答

1

計算cv::absdiff後圖像中包含該改變了它的價值每一個像素的非零值。所以你想要使用改變了的所有圖像區域。

cv::Mat deltaImg; 
cv::absdiff(currImg,prevImg,deltaImg); 

cv::Mat grayscale; 
cv::cvtColor(deltaImg, grayscale, CV_BGR2GRAY); 

// create a mask that includes all pixel that changed their value 
cv::Mat mask = grayscale>0; 

cv::Mat output; 
currImg.copyTo(output,mask); 

下面是樣本圖像:

先前:

enter image description here

電流:

enter image description here

掩模:

enter image description here

輸出:

enter image description here

,這裏是爲deltaImg附加圖像計算所述掩模之前:如果前景像素具有相同的值

enter image description here

問題發生作爲背景像素,但屬於其他「對象」。您可以使用cv::dilate運算符(後跟cv::erode)填充單個像素間隙。或者,如果您對所更改圖像的其他部分不感興趣,也可能想要提取開始菜單的矩形。

+0

嗨米卡,感謝您的解決方案。但是如何解決你指定的像素匹配問題。 (匹配背景和前景圖像中的像素)。我目前面臨這個問題。謝謝。 – user3239282

+0

嗨米卡,你能指導我如何知道面罩的矩形,這樣我就可以從我的手中抓住那個矩形,這將是我改變的區域w.r.t我的預防。 – user3239282

+0

取決於你減去的背景的質量,它可以很容易或有點困難。在我的示例中,由於不僅啓動菜單出現,而且其他窗口元素也發生了變化,前景蒙版包含完整的側邊欄等。如果情況並非如此,只要在掩碼中找到白色像素的最小/最大座標就會給我正確的矩形。但是由於包含邊欄和其他東西,我會嘗試以不同的方式檢測矩形,也許從掩模圖像中的邊緣檢測開始。 – Micka