[英]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)
緊隨其后的是“侵蝕”和“膨脹”。 之后,我找到最大的輪廓並確定是否有物體。 該算法中使用的圖像如下-
如您所見,檢測正常。 我還有其他一些用於測試算法的前景圖像。 他們給出了令人滿意的結果。我想知道,是否還有其他方法可以更好地實現相同的結果。
PS-所有的前景圖像都是在閃光燈打開的情況下拍攝的。 我曾嘗試過關閉Flash,但圖像中似乎存在很多噪點。
================================================== ===========
編輯2-
使用其他圖片的算法性能-
注意:-背景圖像保持不變。
我懷疑這個問題是否像您在問題中所描述的那么簡單,當我們在現實世界中移動時,它將變得非常復雜。
但是無論如何,假設您只在房間中存在小物體,那么您可以通過識別捕獲的二進制圖像中的連接組件來識別它們,並根據其相對像素大小進行選擇。
這是相同的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
包含對象的圖像:
使用連接的組件標簽檢測到的對象:
您可以考慮的另一種方法是使用運動的結構,重建環境/點雲,並且地板表面上方的點簇屬於您的對象。 也可以將其與背景扣除方法結合使用,以消除導致該方法出現問題的錯誤檢測,例如陰影。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.