OpenCV系列之光流 | 四十八

2021-02-21 深度學習與計算機視覺
我們將了解光流的概念及其使用Lucas-Kanade方法的估計。我們將使用cv.calcOpticalFlowPyrLK()之類的函數來跟蹤視頻中的特徵點。我們將使用cv.calcOpticalFlowFarneback()方法創建一個密集的光流場。光流光流是由物體或照相機的運動引起的兩個連續幀之間圖像物體的視運動的模式。它是2D向量場,其中每個向量都是位移向量,表示點從第一幀到第二幀的運動。考慮下面的圖片(圖片提供:Wikipedia關於Optical Flow的文章)。它顯示了一個球連續5幀運動。箭頭顯示其位移向量。光流在以下領域具有許多應用:考慮第一幀中的像素(在此處添加新維度:時間。之前我們只處理圖像,因此不需要時間)。它在時間之後拍攝的下一幀中按距離移動。因此,由於這些像素相同且強度不變,因此可以說然後採用泰勒級數的右側逼近,去掉常用項並除以得到下面的式子上述方程式稱為光流方程式。在其中,我們可以找到,它們是圖像漸變。同樣,是隨時間變化的梯度。但是(u,v)是未知的。我們不能用兩個未知變量來求解這個方程。因此,提供了幾種解決此問題的方法,其中一種是Lucas-Kanade。Lucas-Kanade 方法之前我們已經看到一個假設,即所有相鄰像素將具有相似的運動。Lucas-Kanade方法在該點周圍需要3x3色塊。因此,所有9個點都具有相同的運動。我們可以找到這9點的。所以現在我們的問題變成了求解帶有兩個未知變量的9個方程組的問題。用最小二乘擬合法可獲得更好的解決方案。下面是最終的解決方案,它是兩個方程式-兩個未知變量問題,求解以獲得解決答案。(用哈裡斯拐角檢測器檢查逆矩陣的相似性。這表示拐角是更好的跟蹤點。)因此,從用戶的角度來看,這個想法很簡單,我們給一些跟蹤點,我們接收到這些光流矢量點。但是同樣存在一些問題。到現在為止,我們只處理小動作,所以當大動作時它就失敗了。為了解決這個問題,我們使用金字塔。當我們上金字塔時,較小的動作將被刪除,較大的動作將變為較小的動作。因此,通過在此處應用Lucas-Kanade,我們可以獲得與尺度一致的光流。OpenCV中的Lucas-KanadeOpenCV在單個函數cv.calcOpticalFlowPyrLK()中提供所有這些功能。在這裡,我們創建一個簡單的應用程式來跟蹤視頻中的某些點。為了確定點,我們使用cv.goodFeaturesToTrack()。我們採用第一幀,檢測其中的一些Shi-Tomasi角點,然後使用Lucas-Kanade光流迭代地跟蹤這些點。對於函數cv.calcOpticalFlowPyrLK(),我們傳遞前一幀,前一點和下一幀。它返回下一個點以及一些狀態碼,如果找到下一個點,狀態碼的值為1,否則為零。我們將這些下一個點迭代地傳遞為下一步中的上一個點。請參見下面的代碼:

import numpy as np
import cv2 as cv
import argparse
parser = argparse.ArgumentParser(description='This sample demonstrates Lucas-Kanade Optical Flow calculation. \
                                              The example file can be downloaded from: \
                                              https://www.bogotobogo.com/python/OpenCV_Python/images/mean_shift_tracking/slow_traffic_small.mp4')
parser.add_argument('image', type=str, help='path to image file')
args = parser.parse_args()
cap = cv.VideoCapture(args.image)
# 用於ShiTomasi拐點檢測的參數
feature_params = dict( maxCorners = 100,
                       qualityLevel = 0.3,
                       minDistance = 7,
                       blockSize = 7 )
# lucas kanade光流參數
lk_params = dict( winSize  = (15,15),
                  maxLevel = 2,
                  criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))
# 創建一些隨機的顏色
color = np.random.randint(0,255,(100,3))
# 拍攝第一幀並在其中找到拐角
ret, old_frame = cap.read()
old_gray = cv.cvtColor(old_frame, cv.COLOR_BGR2GRAY)
p0 = cv.goodFeaturesToTrack(old_gray, mask = None, **feature_params)
# 創建用於作圖的掩碼圖像
mask = np.zeros_like(old_frame)
while(1):
    ret,frame = cap.read()
    frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    # 計算光流
    p1, st, err = cv.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
    # 選擇良好點
    good_new = p1[st==1]
    good_old = p0[st==1]
    # 繪製跟蹤
    for i,(new,old) in enumerate(zip(good_new, good_old)):
        a,b = new.ravel()
        c,d = old.ravel()
        mask = cv.line(mask, (a,b),(c,d), color[i].tolist(), 2)
        frame = cv.circle(frame,(a,b),5,color[i].tolist(),-1)
    img = cv.add(frame,mask)
    cv.imshow('frame',img)
    k = cv.waitKey(30) & 0xff
    if k == 27:
        break
    # 現在更新之前的幀和點
    old_gray = frame_gray.copy()
    p0 = good_new.reshape(-1,1,2)

(此代碼不會檢查下一個關鍵點的正確性。因此,即使任何特徵點在圖像中消失了,光流也有可能找到下一個看起來可能與它接近的下一個點。因此,對於穩健的跟蹤,實際上 應該以特定的時間間隔檢測點。OpenCV樣本附帶了這樣一個樣本,該樣本每5幀發現一次特徵點,並且還對光流點進行了後向檢查,以僅選擇良好的流點。請參閱代碼 samples/python/lk_track.py)。OpenCV中的密集光流Lucas-Kanade方法計算稀疏特徵集的光流(在我們的示例中為使用Shi-Tomasi算法檢測到的角)。OpenCV提供了另一種算法來查找密集的光流。它計算幀中所有點的光通量。它基於Gunner Farneback的算法,在2003年Gunner Farneback的「基於多項式展開的兩幀運動估計」中對此進行了解釋。下面的示例顯示了如何使用上述算法找到密集的光流。我們得到一個帶有光流矢量(u,v)(u,v)的2通道陣列。我們找到了它們的大小和方向。我們對結果進行顏色編碼,以實現更好的可視化。方向對應於圖像的色相值。幅度對應於值平面。請參見下面的代碼:

import numpy as np
import cv2 as cv
cap = cv.VideoCapture(cv.samples.findFile("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()
    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('opticalfb.png',frame2)
        cv.imwrite('opticalhsv.png',bgr)
    prvs = next

☆☆☆為方便大家查閱,小編已將OpenCV-Python專欄文章統一整理到公眾號底部菜單欄,同步更新中,關注公眾號,點擊左下方「文章」,如圖:或點擊下方「閱讀原文」,進入OpenCV-Python專欄,即可查看系列文章。


相關焦點

  • OpenCV-Python 光流|四十八
    我們將使用cv.calcOpticalFlowFarneback()方法創建一個密集的光流場。光流光流是由物體或照相機的運動引起的兩個連續幀之間圖像物體的視運動的模式。它是2D向量場,其中每個向量都是位移向量,表示點從第一幀到第二幀的運動。
  • opencv教程-光流法
    opencv裡的光流法有兩種,稀疏光流法 和 稠密光流法。簡單理解的話光流就是一個向量,包含在一定時間間隔內x方向位置的變化、y方向位置的變化,所以其三個主要因素就是dx,dy,dt。主要輸入:prevImg:前一張灰度圖nextImg:當前圖片prevPts:要匹配的點(比如拐點、角點),float主要輸出:nextPts:根據prevPts以及當前圖像計算的新點status:nextPts與prevPts是否匹配狀態,1為匹配,0為不匹配err:光流點匹配的錯誤信息
  • OpenCV 之 霍夫變換
    #include "opencv2/imgcodecs.hpp"#include "opencv2/highgui.hpp"#include "opencv2/imgproc.hpp"using#include <opencv2/imgproc.hpp>#include <opencv2/highgui.hpp>using namespace cv;using
  • 異常檢測常用光流法量化對比:Farneback/Horn-Schunck / Lucas...
    快速獲得最新乾貨本文由博主VG-Lin授權發布,禁止二次轉載三種光流法的OpenCV-API(一) Horn-Schunck光流法CalcOpticalFlowHSHorn–Schunck光流算法用一種全局方法估計圖像的稠密光流場(即對圖像中的每個像素計算光流)算法原理參考論文:Determining
  • 如何快速簡單的安裝opencv-python
    這樣就會從清華鏡像安裝opencv-contrib-python庫。目前opencv最新版本為4.1.1 ----2019-8-28在opencv-contrib-python 版本中含有額外模塊( Extra modules ),而 opencv-python 版本中只含有基礎模塊。
  • 基於TensorFlow 、OpenCV 和 Docker 的實時視頻目標檢測
    安裝 OpenCv 並編譯:# Install OpenCVRUN git clone https://github.com/opencv/opencv.git /usr/local/src/opencvRUN cd /usr/local/src/opencv/ && mkdir
  • OpenCV中的快速直線檢測
    cv::ximgproc::FastLineDetectors是opencv-contrib中用於檢測直線的模塊,該方法能在較短時間內獲得精度較高的直線檢測結果
  • 世界上最好的語言PHP:OpenCV與計算機視覺已在我掌控之下
    選自Medium作者:Vladimir Goncharov機器之心編譯參與:Huiyuan Zhuo、思源、劉曉坤本文首發於公眾號機器之心(ID:almosthuman2014),部分代碼格式有誤可參閱原文章。就像許多開發人員一樣,我也經常使用別人的工作成果(Medium 上的文章、GitHub 上的代碼等),因此也很樂意與社區分享我的成果。
  • 基於opencv 的圖像處理入門教程
    https://github.com/ccc013/CodesNotes/blob/master/opencv_notes/opencv_image_process_tutorial.ipynb1.安裝OpenCV 的安裝還是比較簡單的,直接用 pip 命令在命令行安裝即可,輸入以下命令:pip install opencv-python驗證是否安裝成功,可以運行 python 命令,然後分別輸入以下命令:import cv2
  • 「python opencv視覺零基礎」十四、直方圖反向投影
    前文提醒:博主正在參加博客之星評比,成功入選Top200,現在暫居第九歡迎各位點擊了解更多幫我投票,非常感謝~目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python
  • 「python opencv視覺零基礎」十、圖片效果毛玻璃
    一、學習目標了解高斯模糊的使用方法了解毛玻璃的圖片效果添加了解如何自己做一個噪聲圖片目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python opencv視覺入門到實戰
  • 「python opencv計算機視覺零基礎到實戰」九模糊
    一、學習目標了解什麼是卷積了解模糊的使用方法與應用目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python opencv視覺入門到實戰」 第四節色彩空間
  • 《火炬之光2》漂泊者飛鏢雙槍流打法及加點攻略
    導 讀《火炬之光2》漂泊者雙槍流作為遠程攻擊也有著很高的輸出,不少玩家也都是雙槍的玩法,下面請看由「alex2129」帶來的《火炬之光2》漂泊者飛鏢雙槍流打法及加點攻略
  • 《火炬之光》幽暮法師電極觸發流BD玩法介紹 電極觸發流BD玩法技巧
    導 讀 火炬之光3幽暮法師是遊戲中非常熱門的職業,那麼火炬之光3幽暮法師電極觸發流BD怎麼玩?今天為大家帶來詳細的玩法攻略,一起來看看吧!
  • 斬赤紅之瞳:帝具戰沒有贏家,四十八件帝具已經毀去近半
    可當艾斯德斯回歸帝國後,這場「小偷與警察」的戰鬥就不斷升級,帝具也在戰鬥中毀掉一件又一件,四十八件帝具在戰鬥結束後已經毀去近半!夜襲毀去帝具名單「惡鬼纏身。」這是一件可以根據使用者靈魂需求不斷進化的超強帝具,也是大哥布蘭德傳承給塔茲米的一種意志,是四十八件帝具中唯二的鎧甲型帝具,最後在與帝國的決戰中毀去,無法修復。「浪漫炮臺。」
  • 「python opencv視覺零基礎實戰」七邏輯運算應用
    一、學習目標了解opencv中圖像的邏輯運算了解opencv中邏輯運算的應用如有錯誤歡迎指出~目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python
  • 「python opencv視覺零到實戰」八、圖片選區操作
    一、學習目標了解什麼是ROI了解floodFill的使用方法如有錯誤歡迎指出~目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python opencv視覺入門到實戰
  • 基於OpenCv 和 Python 的手指識別及追蹤
    翻譯 | 餘杭 Lamaric 校對 | 吳曉曼 審核 | 餘杭詳細代碼參考:https://github.com/amarlearning/opencv手指追蹤是許多計算機視覺應用的重要特徵。在該應用中,使用基於直方圖的方法將手與背景幀分離。
  • 「深度學習之opencv」Mat數據的矩陣輸出
    C++中使用opencv的時候,我們有事想看一下我們的圖像的數據,那麼怎麼將一個圖像數據輸出呢?
  • OpenCV(四)邊緣檢測
    我們上一篇文章末尾的例子(opencv自帶的例子)就是使用的Canny算子進行的邊緣檢測的展示。其中也包含了這兩個核心的設置,模糊和閾值。這兩個更詳細的demo都是opencv自帶的例子,尤其第二個是可以實時從攝像頭獲取數據並檢測繪製的。我們之前還沒有接觸過有關的內容,但是之後的章節將會不斷接觸。Laplacian 算子是n維歐幾裡德空間中的一個二階微分算子,可以用於圖像增強或者邊緣提取。