opencv-视频分析

参考:

1、http://docs.opencv.org/3.3.0/  官方文档api

2、http://docs.opencv.org/3.3.0/d6/d00/tutorial_py_root.html 官方英文教程

3、https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html

4、https://github.com/makelove/OpenCV-Python-Tutorial# 进阶教程

5、https://docs.opencv.org/3.3.0/index.html  官方英文教程

6、https://github.com/abidrahmank/OpenCV2-Python-Tutorials

7、https://www.learnopencv.com/

8、http://answers.opencv.org/questions/ OpenCV论坛

9、https://github.com/opencv/opencv   官方github

10、https://github.com/abidrahmank/OpenCV2-Python-Tutorials


注:安装的版本 opencv_python-3.3.0-cp36-cp36m-win_amd64.whl



参考:https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html



Meanshift and Camshift

OpenCV中的平移(Meanshift)

在OpenCV中使用meanshift,首先我们需要设置目标,找到它的直方图,以便我们可以在每个框架上反投影目标来计算均值。 我们还需要提供窗口的初始位置。 对于直方图,这里只考虑色相。 另外,为了避免由于低光引起的错误值,使用 cv2.inRange()函数丢弃低光值。

import numpy as np
import cv2

cap = cv2.VideoCapture('slow.flv')

# take first frame of the video
ret,frame = cap.read()

# setup initial location of window
r,h,c,w = 250,90,400,125  # simply hardcoded the values
track_window = (c,r,w,h)

# set up the ROI for tracking
roi = frame[r:r+h, c:c+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)

# Setup the termination criteria, either 10 iteration or move by atleast 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 meanshift to get the new location
        ret, track_window = cv2.meanShift(dst, track_window, term_crit)

        # Draw it on image
        x,y,w,h = track_window
        img2 = cv2.rectangle(frame, (x,y), (x+w,y+h), 255,2)
        cv2.imshow('img2',img2)

        k = cv2.waitKey(60) & 0xff
        if k == 27:
            break
        else:
            cv2.imwrite(chr(k)+".jpg",img2)

    else:
        break

cv2.destroyAllWindows()
cap.release()

OpenCV的Camshift

它几乎与 meanshift一样,但它返回一个旋转的矩形(这是我们的结果)和框参数(用于在下一次迭代中作为搜索窗口传递)。 请参阅以下代码:

import numpy as np
import cv2

cap = cv2.VideoCapture('slow.flv')

# take first frame of the video
ret,frame = cap.read()

# setup initial location of window
r,h,c,w = 250,90,400,125  # simply hardcoded the values
track_window = (c,r,w,h)

# set up the ROI for tracking
roi = frame[r:r+h, c:c+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)

# Setup the termination criteria, either 10 iteration or move by atleast 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 meanshift 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)
        cv2.imshow('img2',img2)

        k = cv2.waitKey(60) & 0xff
        if k == 27:
            break
        else:
            cv2.imwrite(chr(k)+".jpg",img2)

    else:
        break

cv2.destroyAllWindows()
cap.release()


Optical Flow

OpenCV中的Lucas-Kanade Optical Flow

OpenCV在单个函数 cv2.calcOpticalFlowPyrLK()中提供所有这些。 在这里,我们创建一个简单的应用程序来跟踪视频中的某些点。 要确定点数,我们使用 cv2.goodFeaturesToTrack()。 我们采取第一帧,检测一些Shi-Tomasi角点,然后我们迭代地使用Lucas-Kanade光流跟踪这些点。 对于函数 cv2.calcOpticalFlowPyrLK()我们传递前一帧,先前的点和下一帧。 它返回下一个点以及一些状态数字,如果找到下一个点,其值为1,否则为零。 我们迭代地将这些下一个点作为下一步中的前一点。 请参阅以下代码:

import numpy as np
import cv2

cap = cv2.VideoCapture('slow.flv')

# params for ShiTomasi corner detection
feature_params = dict( maxCorners = 100,
                       qualityLevel = 0.3,
                       minDistance = 7,
                       blockSize = 7 )

# Parameters for lucas kanade optical flow
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, (a,b),(c,d), color[i].tolist(), 2)
        frame = cv2.circle(frame,(a,b),5,color[i].tolist(),-1)
    img = cv2.add(frame,mask)

    cv2.imshow('frame',img)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

    # Now update the previous frame and previous points
    old_gray = frame_gray.copy()
    p0 = good_new.reshape(-1,1,2)

cv2.destroyAllWindows()
cap.release()
(此代码不检查下一个关键点的正确性,因此即使图像中的任何一个特征点消失,也有可能发现下一个点可能看起来很接近,所以实际上对于一个强大的跟踪角落 应该在特定的间隔内检测点,OpenCV样品出现这样一个样本,每5帧找到一个特征点,并且还对所选择的光流点进行反向检查, samples/python2/lk_track.py)。


OpenCV中的 Dense Optical Flow

Lucas-Kanade方法计算稀疏特征集的光流(在我们的示例中,使用Shi-Tomasi算法检测到的角)。 OpenCV提供了另一种算法来找到密集的光流。 它计算帧中所有点的光流。 它是基于Gunner Farneback的算法,它在2003年由Gunner Farneback在“Two-Frame Motion Estimation Based on Polynomial Expansion”中解释。

以下示例显示了如何使用上述算法找到致密光流。 我们得到一个带有光流向量(u,v)的2通道阵列。 我们发现它们的大小和方向。 我们对结果进行颜色编码,以便更好地显示。 方向对应于图像的色相值。 大小对应于值平面。 请参阅以下代码:

import cv2
import numpy as np
cap = cv2.VideoCapture("vtest.avi")

ret, frame1 = cap.read()
prvs = cv2.cvtColor(frame1,cv2.COLOR_BGR2GRAY)
hsv = np.zeros_like(frame1)
hsv[...,1] = 255

while(1):
    ret, frame2 = cap.read()
    next = cv2.cvtColor(frame2,cv2.COLOR_BGR2GRAY)

    flow = cv2.calcOpticalFlowFarneback(prvs,next, None, 0.5, 3, 15, 3, 5, 1.2, 0)

    mag, ang = cv2.cartToPolar(flow[...,0], flow[...,1])
    hsv[...,0] = ang*180/np.pi/2
    hsv[...,2] = cv2.normalize(mag,None,0,255,cv2.NORM_MINMAX)
    rgb = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR)

    cv2.imshow('frame2',rgb)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
    elif k == ord('s'):
        cv2.imwrite('opticalfb.png',frame2)
        cv2.imwrite('opticalhsv.png',rgb)
    prvs = next

cap.release()
cv2.destroyAllWindows()
OpenCV comes with a more advanced sample on dense optical flow, please see samples/python2/opt_flow.py .


Exercises

  1. Check the code in samples/python2/lk_track.py. Try to understand the code.
  2. Check the code in samples/python2/opt_flow.py. Try to understand the code.


背景减法

BackgroundSubtractorMOG

它是一种基于高斯混合的背景/前景分割算法。 在2001年由P.KadewTraKuPong和R.Bowden的论文“改进的用于实时跟踪的背景混合模型”中引入了该方法。它使用一种通过K高斯分布的混合来对每个背景像素进行建模的方法 K = 3〜5)。 混合物的重量代表这些颜色停留在场景中的时间比例。 可能的背景颜色是保持更长和更静态的背景颜色。

编码时,我们需要使用函数cv2.createBackgroundSubtractorMOG()创建一个后台对象。 它具有一些可选的参数,如历史长度,高斯混合数,阈值等。它全部设置为一些默认值。 然后在视频循环内,使用backgroundsubtractor.apply()方法获取前景mask。

import numpy as np
import cv2


cap = cv2.VideoCapture('vtest.avi')

fgbg = cv2.createBackgroundSubtractorMOG()

while(1):
    ret, frame = cap.read()

    fgmask = fgbg.apply(frame)

    cv2.imshow('frame',fgmask)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

cap.release()
cv2.destroyAllWindows()


BackgroundSubtractorMOG2

它也是基于高斯混合的背景/前景分割算法。 它基于Z.Zivkovic的两篇论文,2004年的“改进的背景扣除自适应高斯混合模型”和“2006年背景减法任务的每个图像像素的有效自适应密度估计”。该算法的一个重要特征是 它为每个像素选择适当数量的高斯分布。 (记住,在最后一种情况下,我们在整个算法中采用了K高斯分布)。 它可以更好地适应不同场景的照明变化等。

如前所述,我们必须创建一个背景减法器对象。 在这里,您可以选择是否检测到阴影。 如果 detectShadows   =   True(默认为true),它会检测并标记阴影,但会降低速度。 阴影将以灰色标记。

import numpy as np
import cv2

cap = cv2.VideoCapture('vtest.avi')

fgbg = cv2.createBackgroundSubtractorMOG2()

while(1):
    ret, frame = cap.read()

    fgmask = fgbg.apply(frame)

    cv2.imshow('frame',fgmask)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

cap.release()
cv2.destroyAllWindows()


BackgroundSubtractorGMG

该算法结合统计背景图像估计和每像素贝叶斯分割。

它使用前几个(默认为120)帧进行后台建模。它采用概率前景分割算法,使用贝叶斯推理识别可能的前景对象。估计是适应性的较新观测值比旧观测值更重,以适应可变照明。进行几个形状过滤操作,如关闭和打开,以消除不必要的噪音。在几帧之前你会得到一个黑色的窗口。

import numpy as np
import cv2

cap = cv2.VideoCapture('vtest.avi')

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
fgbg = cv2.createBackgroundSubtractorGMG()

fgbg = cv2.createBackgroundSubtractorKNN()

 while(1): ret, frame = cap.read() fgmask = fgbg.apply(frame) fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel) cv2.imshow('frame',fgmask) k = cv2.waitKey(30) & 0xff if k == 27: breakcap.release()cv2.destroyAllWindows()


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值