私は OpenCV の初心者で、それを学ぶことにしましたが、動きを検出してオブジェクトにバウンディング ボックスを描画する小さなプログラムを作成しています。
2 つのフレームの差を単純に計算し、輪郭を見つけて、オブジェクトの周りに単純な長方形を描くというかなり単純な方法から始めました。これはしばらくの間その目的を果たしましたが、複数のオブジェクトがポップアップしたときに自律的に追跡することはできませんでした. n個のオブジェクトを追跡するには、パラメーターを手動で変更する必要がありました。
そこで、メソッドを変更して代わりに を使用することにしBackgroundSubtractorMOG
ました。この方法は、私が達成しようとしているものにより適していますが、現在私が抱えている唯一の問題は、適用後に検出されたオブジェクトの輪郭を描く方法BackgroundSubtractorMOG
です。長方形はもう必要ありません。代わりに、オブジェクトの境界線の周りに描画したいのです。
import sys
import cv2
def getImageDifference(first, second):
return cv2.absdiff(first, second)
def drawRectangle(contour, frame):
(x, y, w, h) = cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
previousFrame = None
backgroundSubtractor = None
camera = cv2.VideoCapture(0)
backgroundSubtractor = cv2.BackgroundSubtractorMOG()
while True:
grabbed, frame = camera.read()
if not grabbed:
break
fgMask = backgroundSubtractor.apply(frame, learningRate = 1.0/10)
output = cv2.GaussianBlur(fgMask, (21, 21), 0)
if previousFrame is None:
previousFrame = fgMask
continue
frameDelta = getImageDifference(previousFrame, output)
maskRGB = cv2.cvtColor(fgMask,cv2.COLOR_GRAY2BGR)
frameDela = maskRGB
# frameDelta = cv2.cvtColor(fgMask, cv2.COLOR_BGR2GRAY)
threshold = cv2.threshold(fgMask, 21, 255, cv2.THRESH_BINARY)[1]
threshold = cv2.dilate(threshold, None, iterations = 2)
contours, hierarchy = cv2.findContours(threshold.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
sortedContours = sorted(contours, key = cv2.contourArea, reverse = True)[:2] #this will track two objects simultaneously. If I want more, I'd have to come and change this value to whatever I want
for contour in sortedContours:
drawRectangle(contour, frame)
previousFrame = output
draw = frame & maskRGB
cv2.imshow('Main',frame)
cv2.imshow('Background Subtraction', fgMask)
cv2.imshow('Background Subtraction with color', draw)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
camera.release()
cv2.destroyAllWindows()