簡體   English   中英

如何使用OpenCV檢測圖像幀中的對象?

[英]How can I detect an object in image frame using OpenCV?

我正在使用Raspberry Pi開發流浪者,它將掃盪整個房間並撿起掉落在地上的物體。 為了檢測物體,我使用了參考圖像,該圖像在流動站操作開始時即獲取,並且每10秒單擊一次圖像(新圖像)。 為了確定圖像幀中是否有變化,我在參考圖像和新圖像之間進行了圖像減法。 如果發現任何差異,它將在其周圍繪制一個輪廓,並且如果輪廓區域大於某個閾值(警告步驟),則得出存在對象的結論。

我正在使用以下代碼-

import numpy as np
import cv2,time

img=cv2.imread("object1.jpg")
img1=cv2.imread("object2.jpg")
sub=cv2.subtract(img,img1)

gray=cv2.cvtColor(sub,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(3,3),0)
_, contours, _= cv2.findContours(blur,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
c=max(contours,key=cv2.contourArea)
print(cv2.contourArea(c))

if cv2.contourArea>20000:
   print("Object detected !")

上面的代碼僅使用2張圖像來計算它們之間的差異並確定是否存在對象。請注意,我沒有在此處發布將在我的項目中使用的原始代碼。

現在,上述代碼適用於非常受控的情況,例如,當圖像背景非常恆定或其中不存在陰影時。 但是考慮到流動站將在房間中四處走動的事實,並且即使框架中沒有真實物體,照明變化也有可能觸發虛假物體檢測。 差異可能是由於陰影效果造成的輪廓錯誤而觸發的。

我想知道,是否還有其他方法可以在不進行前景/背景圖像減法的情況下實現此目標檢測。 我還考慮過使用超聲波傳感器來檢測物體的存在,但是這不是一個非常可靠的選擇。 我更喜歡基於圖像處理的解決方案。

謝謝 。

================================================== ========================

編輯1-

因此,我決定對算法進行一些更改。 我已經對前景圖像和背景圖像都進行了閾值處理,然后在二進制圖像之間進行了抽象處理,以獲得任何幀change(object)。 代碼如下-

import numpy as np
import cv2,time

img1=cv2.imread("back.jpeg")
blur1 = cv2.GaussianBlur(img1,(5,5),0)
gray1=cv2.cvtColor(blur1,cv2.COLOR_BGR2GRAY)
ret,thresh1 = cv2.threshold(gray1,65,255,cv2.THRESH_BINARY_INV)

img2=cv2.imread("front.jpeg")
blur2 = cv2.GaussianBlur(img2,(5,5),0)
gray2=cv2.cvtColor(blur2,cv2.COLOR_BGR2GRAY)
ret,thresh2 = cv2.threshold(gray2,65,255,cv2.THRESH_BINARY_INV)

diff=cv2.absdiff(thresh2,thresh1)
diff=cv2.bitwise_xor(diff,thresh1)

kernel = np.ones((2,2),np.uint8)
diff=cv2.erode(diff,kernel,iterations = 1)
diff=cv2.dilate(diff,kernel,iterations = 8)

_, contours, _= cv2.findContours(diff,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
c=max(contours,key=cv2.contourArea)
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(diff,(x,y),(x+w,y+h),(125,125,125),2)


cv2.imshow("thresh",diff)
cv2.waitKey(0)

緊隨其后的是“侵蝕”和“膨脹”。 之后,我找到最大的輪廓並確定是否有物體。 該算法中使用的圖像如下-

  1. 背景圖片- 背景圖片

  2. 前景圖像- 前景圖像

  3. 前景閾值- 前景閾值圖像

  4. 背景閾值- 背景閾值圖像

  5. 具有輪廓及其邊界的差分圖像- 最終圖像。

如您所見,檢測正常。 我還有其他一些用於測試算法的前景圖像。 他們給出了令人滿意的結果。我想知道,是否還有其他方法可以更好地實現相同的結果。

PS-所有的前景圖像都是在閃光燈打開的情況下拍攝的。 我曾嘗試過關閉Flash,但圖像中似乎存在很多噪點。

================================================== ===========

編輯2-

使用其他圖片的算法性能-

注意:-背景圖像保持不變。

  1. 對象1- 前景圖像1
  2. 對象1檢測- 前景圖像1結果

我懷疑這個問題是否像您在問題中所描述的那么簡單,當我們在現實世界中移動時,它將變得非常復雜。

但是無論如何,假設您只在房間中存在小物體,那么您可以通過識別捕獲的二進制圖像中的連接組件來識別它們,並根據其相對像素大小進行選擇。

這是相同的Python實現:

img = cv2.imread('D:/Image/objects.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# binarize the image
ret, bw = cv2.threshold(gray, 128, 255, 
cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

# find connected components
connectivity = 4
nb_components, output, stats, centroids = 
cv2.connectedComponentsWithStats(bw, connectivity, cv2.CV_32S)
sizes = stats[1:, -1]; nb_components = nb_components - 1
min_size = 250 #threshhold value for objects in scene
img2 = np.zeros((img.shape), np.uint8)
for i in range(0, nb_components+1):
    # use if sizes[i] >= min_size: to identify your objects
    color = np.random.randint(255,size=3)
    # draw the bounding rectangele around each object
    cv2.rectangle(img2, (stats[i][0],stats[i][1]),(stats[i][0]+stats[i][2],stats[i][1]+stats[i][3]), (0,255,0), 2)
    img2[output == i + 1] = color

包含對象的圖像:

原始圖片

使用連接的組件標簽檢測到的對象:

CNN圖片

您可以考慮的另一種方法是使用運動的結構,重建環境/點雲,並且地板表面上方的點簇屬於您的對象。 也可以將其與背景扣除方法結合使用,以消除導致該方法出現問題的錯誤檢測,例如陰影。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM