Отслеживание и обнаружение объектов являются фундаментальными задачами компьютерного зрения. OpenCV предоставляет два популярных алгоритма для этих задач: MeanShift и CAMShift. MeanShift — это базовый алгоритм отслеживания, а CAMShift — это расширение MeanShift, которое хорошо работает с объектами разных размеров. Идея этого алгоритма состоит в том, чтобы переместить небольшое окно (набор пикселей объектов), чтобы получить пиксели высокой плотности, такие же, как при обратной проекции гистограммы.
вы можете обнаружить, что поток в целом один и тот же, за исключением нескольких одной или двух функций, но разница в результатах обоих алгоритмов очень ощутима…
Ход обоих алгоритмов таков:…
- Сначала настройте цель и найдите ее гистограмму для обратного проецирования цели.
- Также установите одно начальное местоположение
- Установите критерии завершения
Среднее смещение:….
import cv2 # Open a video capture object cap = cv2.VideoCapture('video.mp4') # Read the first frame ret, frame = cap.read() # Define a region of interest (ROI) for tracking x, y, w, h = 300, 200, 100, 100 roi = frame[y:y+h, x:x+w] # Convert the ROI to HSV color space hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) # Calculate the histogram of the ROI roi_hist = cv2.calcHist([hsv_roi], [0], None, [180], [0, 180]) cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX) # Set the termination criteria for MeanShift term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1) while True: ret, frame = cap.read() if not ret: break # Convert the frame to HSV color space hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # Calculate the back projection using the histogram dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1) # Apply MeanShift to get the new location of the object ret, track_window = cv2.meanShift(dst, (x, y, w, h), term_crit) # Draw the tracked window on the frame x, y, w, h = track_window cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) # Display the result cv2.imshow('MeanShift Tracking', frame) if cv2.waitKey(30) & 0xFF == 27: # Press 'Esc' to exit break cap.release() cv2.destroyAllWindows()
Другой фрагмент кода для того же алгоритма:…
import numpy as np import cv2 as cv cap = cv.VideoCapture('C:\\Users\\RANGER\\Desktop\\Computer_Vision_Opencv\\image data\\Roadside.mp4') # take first frame of the video ret, frame = cap.read() # setup initial location of window 318,336,454,488 #577,469,667,686, 480,405,531,581 #x, y, width, height = 318, 454, 336,488 x, y, width, height = 581,405,531,480 track = (x, y ,width, height) # set up the ROI for tracking roi = frame[y:y+height, x : x+width] # passing an individual object location in video . hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV) # we need histogram below so we need to convert ROI to HSV. mask = cv.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255))) # those array are specific array which will define threshold. roi_hist = cv.calcHist([hsv_roi], [0], mask, [180], [0, 180]) # creating histogram after masking. cv.normalize(roi_hist, roi_hist, 0, 255,cv.NORM_MINMAX) # Setup the termination criteria, either 10 iteration or move by atleast 1 pt termntn = ( cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1) cv.imshow('roi',roi) while True: ret, frame = cap.read() if ret == True: hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV) dst = cv.calcBackProject([hsv], [0], roi_hist, [0, 180], 1) # apply meanshift to get the new location ret, track = cv.meanShift(dst, track, termntn) # Draw it on image x,y,w,h = track final = cv.rectangle(frame, (x,y), (x+w, y+h), (0,0,255), 3) #cv.imshow('dst', dst) frame = cv.resize(final,(600,600)) cv.imshow('final_image',frame) k = cv.waitKey(30) & 0xff if k == 27: break else: break cv.destroyAllWindows()
Выход:…
Недостатки этого алгоритма в том, что
- Фиксированное целевое окно не должно быть изменено
- Другой вариант — сохранить цель в списке или словаре, а затем использовать ее.
- Но в любом случае придется делать вручную…
CAMshift:….
CAMShift расширяет MeanShift, адаптируя размер окна поиска в зависимости от изменений формы и размера объекта. Полная форма CAMshift — «Непрерывно адаптивный средний сдвиг».
import cv2 cap = cv2.VideoCapture('video.mp4') ret, frame = cap.read() x, y, w, h = 300, 200, 100, 100 track_window = (x, y, w, h) roi = frame[y:y+h, x:x+w] hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV) roi_hist = cv2.calcHist([hsv_roi], [0], None, [180], [0, 180]) cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX) term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1) while True: ret, frame = cap.read() if not ret: break hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1) ret, track_window = cv2.CamShift(dst, track_window, term_crit) pts = cv2.boxPoints(ret) pts = np.int0(pts) img2 = cv2.polylines(frame, [pts], True, (0, 255, 0), 2) cv2.imshow('CAMShift Tracking', img2) if cv2.waitKey(30) & 0xFF == 27: break cap.release() cv2.destroyAllWindows()
Другой фрагмент кода для того же алгоритма:….
import numpy as np import cv2 as cv cap = cv.VideoCapture('C:\\Users\\RANGER\\Desktop\\Computer_Vision_Opencv\\image data\\Roadside.mp4') # take first frame of the video ret, frame = cap.read() # setup initial location of window #x, y, width, height = 580, 30, 80,150 x, y, width, height = 318, 454, 336,488 track = (x, y ,width, height) # set up the ROI for tracking roi = frame[y:y+height, x : x+width] hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV) mask = cv.inRange(hsv_roi, np.array((0., 60., 32.)), np.array((180., 255., 255))) roi_hist = cv.calcHist([hsv_roi], [0], mask, [180], [0, 180]) cv.normalize(roi_hist, roi_hist, 0, 255,cv.NORM_MINMAX) # Setup the termination criteria, either 10 iteration or move by atleast 1 pt termntn = ( cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1) cv.imshow('roi',roi) while True: ret, frame = cap.read() if ret == True: hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV) dst = cv.calcBackProject([hsv], [0], roi_hist, [0, 180], 1) # apply meanshift to get the new location ret, track = cv.CamShift(dst, track, termntn) # Draw it on image #x,y,w,h = track #final = cv.rectangle(frame, (x,y), (x+w, y+h), (0,0,255), 3) #Try to draw rotating rectangle pts =cv.boxPoints(ret) pts = np.int64(pts) final = cv.polylines(frame,[pts],True,(255,0,0),2) cv.imshow('dst', dst) frame = cv.resize(final,(600,600)) cv.imshow('final_image',frame) k = cv.waitKey(30) & 0xff if k == 27: break else: break cv.destroyAllWindows()
Выход :…..
Замените 'video.mp4'
на путь к вашему видеофайлу. В обоих примерах отслеживаемый объект будет показан с ограничивающей рамкой вокруг него. CAMShift обычно работает лучше при изменении размера объекта.
Для получения дополнительной информации об этих алгоритмах посетите https://docs.opencv.org/4.x/d7/d00/tutorial_meanshift.html.