視頻分析
學習使用 Meanshift 和 Camshift 算法在視頻中找到并跟蹤目標對象:
Meanshift算法
Meanshift 算法的基本原理是和很簡單的。假設我們有一堆點(比如直方
圖反向投影得到的點),和一個小的圓形窗口,我們要完成的任務就是將這個窗
口移動到最大灰度密度處(或者是點最多的地方)。如下圖所示:
初始窗口是藍色的“C1”,它的圓心為藍色方框“C1_o”,而窗口中所有點質心卻是“C1_r”(小的藍色圓圈),很明顯圓心和點的質心沒有重合。所以移動圓心 C1_o 到質心 C1_r,這樣我們就得到了一個新的窗口。這時又可以找到新窗口內所有點的質心,大多數情況下還是不重合的,所以重復上面的操作:將新窗口的中心移動到新的質心。就這樣不停的迭代操作直到窗口的中心和其所包含點的質心重合為止(或者有一點小誤差)。按照這樣的操作我們的窗口最終會落在像素值(和)最大的地方。如上圖所示“C2”是窗口的最后位址,我們可以看出來這個窗口中的像素點最多。
要在 OpenCV 中使用 Meanshift 算法首先我們要對目標對象進行設置,
計算目標對象的直方圖,這樣在執(zhí)行 meanshift 算法時我們就可以將目標對
象反向投影到每一幀中去了。另外我們還需要提供窗口的起始位置。在這里我
們值計算 H( Hue)通道的直方圖,同樣為了避免低亮度造成的影響,我們使
用函數 cv2.inRange() 將低亮度的值忽略掉。
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 視頻下載地址https://www.bogotobogo.com/python/OpenCV_Python/images/mean_shift_tracking/slow_traffic_small.mp4
cap = cv2.VideoCapture('./resource/opencv/video/slow_traffic_small.mp4')
ret,frame = cap.read()
# setup initial location of window
x, y, w, h = 300, 200, 100, 50 # simply hardcoded the values
track_window = (x, y, w, h)
# set up the ROI for tracking
roi = frame[y:y+h, x:x+w]
hsv_roi = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
roi_hist = cv2.calcHist([hsv_roi],[0],mask,[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(1):
ret, frame = cap.read()
if ret == True:
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)
ret, track_window = cv2.meanShift(dst, track_window, term_crit)
x,y,w,h = track_window
img2 = cv2.rectangle(frame, (x,y), (x+w, y+h), 255, 2)
k = cv2.waitKey(60)&0xFF
if k == 27:
break
else:
cv2.imshow('img', img2)
else:
break
cap.release()
cv2.destroyAllWindows()
Camshift算法
與 Meanshift 基本一樣,但是返回的結果是一個帶旋轉角度的矩形以及這個矩形的參數(被用到下一次迭代過程中)。
import numpy as np
import cv2
from matplotlib import pyplot as plt
# 視頻下載地址https://www.bogotobogo.com/python/OpenCV_Python/images/mean_shift_tracking/slow_traffic_small.mp4
cap = cv2.VideoCapture('./resource/opencv/video/slow_traffic_small.mp4')
# take first frame of the video
ret, frame = cap.read()
# setup initial location of window
x, y, w, h = 300, 200, 100, 50 # simply hardcoded the values
track_window = (x, y, w, h)
# set up the ROI for tracking
roi = frame[y:y+h, x:x+w]
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
roi_hist = cv2.calcHist([hsv_roi],[0],mask,[180],[0,180])
cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX)
# Setup the termination criteria, either 10 iteration or move by at least 1 pt
term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )
while(1):
ret, frame = cap.read()
if ret == True:
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
dst = cv2.calcBackProject([hsv],[0],roi_hist,[0,180],1)
# apply camshift to get the new location
ret, track_window = cv2.CamShift(dst, track_window, term_crit)
# Draw it on image
pts = cv2.boxPoints(ret)
pts = np.int0(pts)
img2 = cv2.polylines(frame,[pts],True, 255,2)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
else:
cv2.imshow('img2',img2)
else:
cap.release()
cv2.destroyAllWindows()
光流
Lucas-Kanade Optical Flow
- 光流的概念以及 Lucas-Kanade 光流法
- 函數 cv2.calcOpticalFlowPyrLK() 對圖像中的特征點進行跟蹤
import numpy as np
import cv2
cap = cv2.VideoCapture('./resource/opencv/video/slow_traffic_small.mp4')
# params for Shi-Tomasi corner detection
feature_params = dict(maxCorners = 100,
qualityLevel = 0.3,
minDistance = 7,
blockSize = 7)
# parameters for lucas kanade optical flow
# maxLevel 為使用的圖像金字塔層數
lk_params = dict(winSize = (15,15),
maxLevel = 2,
criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
# Create some random colors
color = np.random.randint(0, 255, (100, 3))
# Take first frame and find corners in it
ret, old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)
# Create a mask image for drawing purposes
mask = np.zeros_like(old_frame)
while(1):
ret, frame = cap.read()
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# calculate optical flow 能夠獲取點的新位置
p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
# Select good points
good_new = p1[st==1]
good_old = p0[st==1]
# draw the tracks
for i,(new, old) in enumerate(zip(good_new, good_old)):
a,b = new.ravel()
c,d = old.ravel()
mask = cv2.line(mask, (int(a), int(b)), (int(c), int(d)), color[i].tolist(), 2)
frame = cv2.circle(frame, (int(a), int(b)), 5, color[i].tolist(), -1)
img = cv2.add(frame, mask)
cv2.imshow('frame', img)
k = cv2.waitKey(30) & 0xFF
if k == 27:
break
old_gray = frame_gray.copy()
p0 = good_new.reshape(-1, 1, 2)
cv2.destroyAllWindows()
cap.release()
文章來源:http://www.zghlxwxcb.cn/news/detail-658583.html
Dense Optical Flow
import numpy as np
import cv2 as cv
cap = cv.VideoCapture('./resource/opencv/video/vtest.avi')
ret, frame1 = cap.read()
prvs = cv.cvtColor(frame1, cv.COLOR_BGR2GRAY)
hsv = np.zeros_like(frame1)
hsv[..., 1] = 255
while(1):
ret, frame2 = cap.read()
if not ret:
print('No frames grabbed!')
break
next = cv.cvtColor(frame2, cv.COLOR_BGR2GRAY)
flow = cv.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)
mag, ang = cv.cartToPolar(flow[..., 0], flow[..., 1])
hsv[..., 0] = ang*180/np.pi/2
hsv[..., 2] = cv.normalize(mag, None, 0, 255, cv.NORM_MINMAX)
bgr = cv.cvtColor(hsv, cv.COLOR_HSV2BGR)
cv.imshow('frame2', bgr)
k = cv.waitKey(30) & 0xff
if k == 27:
break
elif k == ord('s'):
cv.imwrite('./resource/opencv/video/opticalfb.png', frame2)
cv.imwrite('./resource/opencv/video/opticalhsv.png', bgr)
prvs = next
cv.destroyAllWindows()
文章來源地址http://www.zghlxwxcb.cn/news/detail-658583.html
到了這里,關于OpenCV-Python中的圖像處理-視頻分析的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!