Итак, я пытался создать трекер движения, чтобы отслеживать движение собаки в видео (записанном сверху вниз), извлекать обрезанное видео, показывающее собаку, и игнорировать остальную часть фона.
Сначала я попытался с отслеживанием объектов, используя доступные алгоритмы в opencv 3 (BOOSTING, MIL, KCF, TLD, MEDIAFLOW, GOTURN (возвращает ошибку, еще не смог ее решить)) из эта ссылка, и я даже пробовал базовый алгоритм отслеживания движения, вычитая первый кадр, но ни один из них дает хороший результат. Ссылка а>
Я бы предпочел код с предустановленным прямоугольником, который окружает область движения после его обнаружения. Что-то вроде этого видео
Я не очень хорошо знаком с OPENCV, но я считаю, что отслеживание одиночного движения не должно быть проблемой, поскольку уже проделано много работы. Должен ли я рассмотреть другие библиотеки/API или есть лучший код/учебник, которому я могу следовать, чтобы сделать это? я хочу использовать это позже с нейронной сетью (поэтому я пытаюсь решить это с помощью python/opencv)
Спасибо за любую помощь/совет
Изменить:
Я удалил предыдущий код, чтобы сделать пост чище.
Кроме того, на основе полученных отзывов и дальнейших исследований я смог изменить некоторый код, чтобы приблизить его к желаемому результату. Однако у меня все еще есть досадная проблема с отслеживанием. Кажется, что первый кадр влияет на остальную часть отслеживания, поскольку даже после того, как собака движется, она продолжает определять свое первое местоположение. Я попытался ограничить отслеживание только одним действием с помощью флага, но обнаружение испортилось. Это код и изображения, показывающие результаты:
jimport imutils
import time
import cv2
previousFrame = None
def searchForMovement(cnts, frame, min_area):
text = "Undetected"
flag = 0
for c in cnts:
# if the contour is too small, ignore it
if cv2.contourArea(c) < min_area:
continue
#Use the flag to prevent the detection of other motions in the video
if flag == 0:
(x, y, w, h) = cv2.boundingRect(c)
#print("x y w h")
#print(x,y,w,h)
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
text = "Detected"
flag = 1
return frame, text
def trackMotion(ret,frame, gaussian_kernel, sensitivity_value, min_area):
if ret:
# Convert to grayscale and blur it for better frame difference
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (gaussian_kernel, gaussian_kernel), 0)
global previousFrame
if previousFrame is None:
previousFrame = gray
return frame, "Uninitialized", frame, frame
frameDiff = cv2.absdiff(previousFrame, gray)
thresh = cv2.threshold(frameDiff, sensitivity_value, 255, cv2.THRESH_BINARY)[1]
thresh = cv2.dilate(thresh, None, iterations=2)
_, cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
frame, text = searchForMovement(cnts, frame, min_area)
#previousFrame = gray
return frame, text, thresh, frameDiff
if __name__ == '__main__':
video = "Track.avi"
video0 = "Track.mp4"
video1= "Ntest1.avi"
video2= "Ntest2.avi"
camera = cv2.VideoCapture(video1)
time.sleep(0.25)
min_area = 5000 #int(sys.argv[1])
cv2.namedWindow("Security Camera Feed")
while camera.isOpened():
gaussian_kernel = 27
sensitivity_value = 5
min_area = 2500
ret, frame = camera.read()
#Check if the next camera read is not null
if ret:
frame, text, thresh, frameDiff = trackMotion(ret,frame, gaussian_kernel, sensitivity_value, min_area)
else:
print("Video Finished")
break
cv2.namedWindow('Thresh',cv2.WINDOW_NORMAL)
cv2.namedWindow('Frame Difference',cv2.WINDOW_NORMAL)
cv2.namedWindow('Security Camera Feed',cv2.WINDOW_NORMAL)
cv2.resizeWindow('Thresh', 800,600)
cv2.resizeWindow('Frame Difference', 800,600)
cv2.resizeWindow('Security Camera Feed', 800,600)
# uncomment to see the tresh and framedifference displays
cv2.imshow("Thresh", thresh)
cv2.imshow("Frame Difference", frameDiff)
cv2.putText(frame, text, (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow("Security Camera Feed", frame)
key = cv2.waitKey(3) & 0xFF
if key == 27 or key == ord('q'):
print("Bye")
break
camera.release()
cv2.destroyAllWindows()
На этом рисунке показано, как самый первый кадр все еще влияет на результаты разности кадров, что заставляет блок покрывать область без движения.
Здесь показан случай, когда движение игнорируется, поскольку несуществующее движение (разница между кадрами второго и первого кадров видео) обнаруживается ложно. Когда я разрешаю множественное отслеживание, он отслеживает оба, что по-прежнему неверно, поскольку обнаруживает пустую область.
У кого-нибудь есть идея, где код неверен или отсутствует? Я продолжаю пытаться, но не могу заставить его работать должным образом.
Заранее спасибо !!