女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于opencv對高空拍攝視頻消抖處理

新機器視覺 ? 來源:AI算法與圖像處理 ? 作者:AI算法與圖像處理 ? 2021-03-20 10:29 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、問題背景

無人機在拍攝視頻時,由于風向等影響因素,不可避免會出現位移和旋轉,導致拍攝出的畫面存在平移和旋轉的幀間變換, 即“抖動” 抖動會改變目標物體 (車輛、行人) 的坐標,給后續的檢測、跟蹤任務引入額外誤差,造成數據集不可用。

原效果

目標效果

理想的無抖動視頻中,對應于真實世界同一位置的背景點在不同幀中的坐標應保持一致,從而使車輛、行人等目標物體的坐標變化只由物體本身的運動導致,而不包含相機的運動 抖動可以由不同幀中對應背景點的坐標變換來描述

二、量化指標

抖動可以用相鄰幀之間的 x 方向平移像素 dx,y 方向平移像素 dy,旋轉角度 da,縮放比例 s 來描述,分別繪制出 4 個折線圖,根據折線圖的走勢可以判斷抖動的程度 理想的無抖動視頻中,dx、dy、da 幾乎始終為 0,s 幾乎始終為 1。

三、技術思路

我們最終實現,將視頻的所有幀都對齊到第一幀,以達到視頻消抖問題,實現邏輯如下圖所示。

97fc0916-88ef-11eb-8b86-12bb97331649.png

(1)首先對視頻進行抽第一幀與最后一幀,為什么抽取兩幀?這樣做的主要目的是,我們在做幀對齊時,使用幀中靜態物的關鍵點做對齊,如果特征點來源于動態物上,那么對齊后就會產生形變,我們選取第一幀與最后一幀,提取特征點,留下交集部分,則可以得到靜態特征點我們這里稱為特征模板,然后將特征模板應用到每一幀上,這樣可以做有效對齊。

(2)常用特征點檢測器:

SIFT: 04 年提出,廣泛應用于各種跟蹤和識別算法,表現能力強,但計算復雜度高。

SURF: 06 年提出,是 SIFT 的演進版本,保持強表現能力的同時大大減少了計算量。

BRISK: BRIEF 的演進版本,壓縮了特征的表示,提高了匹配速度。ORB: 以速度著稱,是 SURF 的演進版本,多用于實時應用。

GFTT: 最早提出的 Harris 角點的改進版本,經常合稱為 Harris-Shi-Tomasi 角點。

SimpleBlob: 使用 blob 的概念來抽取圖像中的特征點,相對于角點的一種創新。FAST: 相比其他方法特征點數量最多,但也容易得到距離過近的點,需要經過 NMS。

Star: 最初用于視覺測距,后來也成為一種通用的特征點檢測方法。

我們這里使用的是SURF特征點檢測器

第一幀特特征點提取

最后一幀特征點提取

(3)在上圖中,我們發現所提取的特征點中部分來自于車身,由于車是運動的,所以我們不能使用,我們用第一幀與最后一幀做靜態特幀點匹配,生成靜態特征模板,在下圖中,我們發現只有所有的特征點只選取在靜態物上

靜態特征點模板

(4)靜態特征模板匹配 ,我們這里使用Flann算法,匹配結果如下

特征匹配

(5)使用匹配成功的兩組特征點,估計兩幀之間的透視變換 (Perspective Transformation)。估計矩陣 H,其中 (x_i, y_i) 和 (x_i^′, y_i^′) 分別是兩幀的特征點。

第一幀

最后一幀對齊到第一幀

四、實現代碼

代碼基于python實現,如下所示

import cv2import timeimport numpy as npimport os class Stable: # 處理視頻文件路徑 __video_path = None # surf 特征提取 __surf = { # surf算法 'surf': None, # 提取的特征點 'kp': None, # 描述符 'des': None, # 過濾后的特征模板 'template_kp': None } # capture __capture = { # 捕捉器 'cap': None, # 視頻大小 'size': None, # 視頻總幀 'frame_count': None, # 視頻幀率 'fps': None, 'video': None } # 配置 __config = { # 要保留的最佳特征的數量 'key_point_count': 5000, # Flann特征匹配 'index_params': dict(algorithm=0, trees=5), 'search_params': dict(checks=50), 'ratio': 0.5, 'frame_count': 9999 } # 當前處理幀數 __current_frame = 0 # 需要處理幀數 __handle_count = 0 # 處理時間 __handle_timer = { 'init': 0, 'handle': 0, 'read': 0, 'key': 0, 'matrix': 0, 'flann': 0, 'perspective': 0, 'write': 0, 'other': 0, } # 幀隊列 __frame_queue = None # 需要寫入的幀隊列 __write_frame_queue = None # 特征提取列表 __surf_list = [] def __init__(self): pass # 初始化capture def __init_capture(self): self.__capture['cap'] = cv2.VideoCapture(self.__video_path) self.__capture['size'] = (int(self.__capture['cap'].get(cv2.CAP_PROP_FRAME_WIDTH)), int(self.__capture['cap'].get(cv2.CAP_PROP_FRAME_HEIGHT))) self.__capture['fps'] = self.__capture['cap'].get(cv2.CAP_PROP_FPS) self.__capture['video'] = cv2.VideoWriter(self.__video_path.replace('.', '_stable.'), cv2.VideoWriter_fourcc(*"mp4v"), self.__capture['fps'], self.__capture['size']) self.__capture['frame_count'] = int(self.__capture['cap'].get(cv2.CAP_PROP_FRAME_COUNT)) self.__handle_count = min(self.__config['frame_count'], self.__capture['frame_count']) # 初始化surf def __init_surf(self): st = time.time() self.__capture['cap'].set(cv2.CAP_PROP_POS_FRAMES, 0) state, first_frame = self.__capture['cap'].read() self.__capture['cap'].set(cv2.CAP_PROP_POS_FRAMES, self.__capture['frame_count'] - 20) state, last_frame = self.__capture['cap'].read() self.__surf['surf'] = cv2.xfeatures2d.SURF_create(self.__config['key_point_count'], 1, 1, 1, 1) # nfeatures:默認為0,要保留的最佳特征的數量。特征按其分數排名(在SIFT算法中按局部對比度排序) # nOctaveLayers:默認為3,金字塔每組(Octave)有多少層。3是D. Lowe紙中使用的值。 # contrastThreshold:默認為0.04,對比度閾值,用于濾除半均勻(低對比度)區域中的弱特征。閾值越大,檢測器產生的特征越少。 # edgeThreshold:默認為10,用來過濾邊緣特征的閾值。注意,它的意思與contrastThreshold不同,edgeThreshold越大,濾出的特征越少(保留更多特征)。 # sigma:默認為1.6,高斯金字塔中的σ。如果使用帶有軟鏡頭的弱相機拍攝圖像,則可能需要減少數量。 self.__surf['kp'], self.__surf['des'] = self.__surf['surf'].detectAndCompute(first_frame, None) kp, des = self.__surf['surf'].detectAndCompute(last_frame, None) # 快速臨近匹配 flann = cv2.FlannBasedMatcher(self.__config['index_params'], self.__config['search_params']) matches = flann.knnMatch(self.__surf['des'], des, k=2) good_match = [] for m, n in matches: if m.distance < self.__config['ratio'] * n.distance: good_match.append(m) self.__surf['template_kp'] = [] for f in good_match: self.__surf['template_kp'].append(self.__surf['kp'][f.queryIdx]) self.__capture['cap'].set(cv2.CAP_PROP_POS_FRAMES, 0) self.__handle_timer['init'] = int((time.time() - st) * 1000) print("[INFO] init time:{}ms".format(self.__handle_timer['init'])) # 初始化 隊列 def __init_data(self): pass # 初始化 def __init(self): self.__init_capture() self.__init_surf() self.__init_data() # 處理 def __process(self): self.__current_frame = 1 while True: if self.__current_frame > self.__handle_count: break start_time = time.time() # 抽幀 success, frame = self.__capture['cap'].read() self.__handle_timer['read'] = int((time.time() - start_time) * 1000) if not success: return # 計算 frame = self.detect_compute(frame) # 寫幀 st = time.time() self.__capture['video'].write(frame) self.__handle_timer['write'] = int((time.time() - st) * 1000) self.__handle_timer['handle'] = int((time.time() - start_time) * 1000) self.__current_frame += 1 self.print_handle_time() # 視頻穩像 def stable(self, path): self.__video_path = path self.__init() self.__process() # 打印耗時 def print_handle_time(self): print( "[INFO] handle frame:{}/{} time:{}ms(read:{}ms key:{}ms flann:{}ms matrix:{}ms perspective:{}ms write:{}ms)". format(self.__current_frame, self.__handle_count, self.__handle_timer['handle'], self.__handle_timer['read'], self.__handle_timer['key'], self.__handle_timer['flann'], self.__handle_timer['matrix'], self.__handle_timer['perspective'], self.__handle_timer['write'])) # 特征點提取 def detect_compute(self, frame): frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 計算特征點 st = time.time() kp, des = self.__surf['surf'].detectAndCompute(frame_gray, None) self.__handle_timer['key'] = int((time.time() - st) * 1000) # 快速臨近匹配 st = time.time() flann = cv2.FlannBasedMatcher(self.__config['index_params'], self.__config['search_params']) matches = flann.knnMatch(self.__surf['des'], des, k=2) self.__handle_timer['flann'] = int((time.time() - st) * 1000) # 計算單應性矩陣 st = time.time() good_match = [] for m, n in matches: if m.distance < self.__config['ratio'] * n.distance: good_match.append(m) p1, p2 = [], [] for f in good_match: # 存在與模板特征點中 if self.__surf['kp'][f.queryIdx] in self.__surf['template_kp']: p1.append(self.__surf['kp'][f.queryIdx].pt) p2.append(kp[f.trainIdx].pt) H, _ = cv2.findHomography(np.float32(p2), np.float32(p1), cv2.RHO) self.__handle_timer['matrix'] = int((time.time() - st) * 1000) # 透視變換 st = time.time() output_frame = cv2.warpPerspective(frame, H, self.__capture['size'], borderMode=cv2.BORDER_REPLICATE) self.__handle_timer['perspective'] = int((time.time() - st) * 1000) return output_frame s = Stable() s.stable('video/test10.mov')

五、效果展示

我們消抖后的視頻道路完全沒有晃動,但是在邊界有馬賽克一樣的東西,那是因為圖片對齊后后出現黑邊,我們采用邊緣點重復來彌補黑邊。

消抖前

消抖后

六、效率優化

目前的處理效率(原視頻尺寸3840*2160),我們可以看出主要時間是花費在特征點(key)提取上。
可以采用異步處理+GPU提高計算效率

ae4ac39c-88ef-11eb-8b86-12bb97331649.png

處理效率

七、存在問題

目前存在的問題 還不能完全消除視頻中的所有抖動

(1)尤其是對于原來的抖動比較劇烈的視頻,目前只能去除大部分明顯抖動;

(2)由于畫面旋轉造成的邊緣畫面缺失,目前采取了復制邊緣點 (replicate) 的操作,是否會對數據集的使用造成影響還需要進行實驗。

改進思路

(1)對于抖動問題,計劃通過調整關鍵點檢測器參數、盡可能過濾掉運動物體的特征點、調整特征點匹配參數來解決;

(2)對于邊緣畫面缺失問題,可以使用基于 CNN 的圖像修復算法,盡可能讓缺失的邊緣表現得更自然 后續進一步增加運動平滑等算法,實現對整體運動的進一步平滑。

責任編輯:lq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 檢測器
    +關注

    關注

    1

    文章

    894

    瀏覽量

    48676
  • gpu
    gpu
    +關注

    關注

    28

    文章

    4944

    瀏覽量

    131218
  • OpenCV
    +關注

    關注

    32

    文章

    642

    瀏覽量

    42874

原文標題:基于opencv對高空拍攝視頻消抖處理

文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    一次諧裝置與二次諧裝置區別、一次諧器與二次諧器的區別

    繞組,處理低電壓信號。 功能側重:一次諧器通過非線性電阻抑制鐵磁諧振,限制中性點位移電壓;二次諧器通過檢測諧振信號并觸發晶閘管短路阻尼電阻,動態消除諧振。 適用場景:一次諧器
    的頭像 發表于 05-07 09:58 ?1100次閱讀
    一次<b class='flag-5'>消</b>諧裝置與二次<b class='flag-5'>消</b>諧裝置區別、一次<b class='flag-5'>消</b>諧器與二次<b class='flag-5'>消</b>諧器的區別

    如何用OpenCV的相機捕捉視頻進行人臉檢測--基于米爾NXP i.MX93開發板

    本文將介紹基于米爾電子MYD-LMX93開發板(米爾基于NXPi.MX93開發板)的基于OpenCV的人臉檢測方案測試。OpenCV提供了一個非常簡單的接口,用于相機捕捉一個視頻(我用的電腦內置
    的頭像 發表于 04-15 11:51 ?338次閱讀
    如何用<b class='flag-5'>OpenCV</b>的相機捕捉<b class='flag-5'>視頻</b>進行人臉檢測--基于米爾NXP i.MX93開發板

    使用OpenCV保存從攝像頭捕獲的視頻時更改顏色輸出視頻收到警告怎么解決?

    保存了從配備 OpenCV* 的攝像頭捕獲的視頻。 生成更改的顏色輸出視頻。 收到警告:[ INFO:0] global .。/opencv/modules/core/src/uti
    發表于 03-05 07:20

    DLP6500FYE使用視頻模式加載圖像,在相機端拍攝到的圖片會閃爍是怎么回事?

    使用視頻模式加載圖像,在相機端拍攝到的圖片會閃爍,具體現象如視頻所示,想請教一下這是什么原因該怎么解決。
    發表于 02-17 07:54

    TVP5150輸出圖像有時有時無是怎么回事?

    我現在使用貴司的TVP5150AM視頻解碼芯片,現在出現一個問題,用顯示器顯示的圖像時有時無,并且有圖像的情況下也有點。 我的方案是用TVP5150進行采集相機輸出的視頻信號,然后通過FPGA
    發表于 01-06 07:28

    RK3568 + OpenCV 會碰撞出什么火花?案例詳解:2-1 基于OpenCV的畫線實驗

    一、實驗目的 本節視頻的目的是了解OpenCV的作用并通過OpenCV實現畫線。 二、實驗原理 OpenCV 開放源代碼計算機視覺庫 OpenCV
    發表于 12-03 14:09

    如何用OpenCV的相機捕捉視頻進行人臉檢測--基于米爾NXP i.MX93開發板

    提供了一個非常簡單的接口,用于相機捕捉一個視頻(我用的電腦內置攝像頭) 1、安裝python3-opencv apt install python3-opencv 2、查看攝像頭支持的格式與分辨率
    發表于 11-15 17:58

    基于OPENCV的相機捕捉視頻進行人臉檢測--米爾NXP i.MX93開發板

    本文將介紹基于米爾電子MYD-LMX93開發板(米爾基于NXPi.MX93開發板)的基于OpenCV的人臉檢測方案測試。OpenCV提供了一個非常簡單的接口,用于相機捕捉一個視頻(我用的電腦內置
    的頭像 發表于 11-07 09:03 ?1471次閱讀
    基于<b class='flag-5'>OPENCV</b>的相機捕捉<b class='flag-5'>視頻</b>進行人臉檢測--米爾NXP i.MX93開發板

    基于FPGA實現按鍵處理

    引言: 按鍵在電子產品中經常用到,由于按鍵的機械特性,按鍵在閉合或松開的瞬間伴隨著一連串的抖動,這樣的抖動將直接影響設計系統的穩定性。因此,必須對抖動進行處理。本文介紹如何在FPGA中實現按鍵
    的頭像 發表于 10-24 14:54 ?1156次閱讀
    基于FPGA實現按鍵<b class='flag-5'>消</b><b class='flag-5'>抖</b><b class='flag-5'>處理</b>

    智能安全帽_AR遠程協助|近電感應|硬件云臺防

    智能安全帽基于聯發科的低功耗處理器,配置有2GB內存和16GB存儲,并運行Android 9.0操作系統。其1300萬像素的高清云臺防攝像頭能夠拍攝1080P高分辨率的視頻,有效還原
    的頭像 發表于 10-15 20:27 ?917次閱讀
    智能安全帽_AR遠程協助|近電感應|硬件云臺防<b class='flag-5'>抖</b>

    兩種常見的硬件實現方式

    由于機械按鍵在操作過程中會產生抖動現象,這種抖動信號如果不加以處理,就可能導致單片機等電子設備誤判按鍵狀態,從而引發錯誤操作。本文將詳細介紹兩種常見的硬件實現方式:RS觸發器和電容濾波。 RS
    的頭像 發表于 09-25 16:54 ?3724次閱讀
    兩種常見的硬件<b class='flag-5'>消</b><b class='flag-5'>抖</b>實現方式

    為什么按鍵那么重要

    和錯誤操作。因此,進行按鍵處理顯得尤為重要。 按鍵抖動的產生是由于機械觸點的彈性特性所決定的。當按鍵被按下或釋放時,觸點并不會立即穩定地接通或斷開,而是會在閉合和斷開的瞬間產生一連串的抖動信號。這些抖動信號
    的頭像 發表于 09-25 16:50 ?1292次閱讀
    為什么按鍵<b class='flag-5'>消</b><b class='flag-5'>抖</b>那么重要

    【龍芯2K0300蜂鳥板試用】5 搭建opencv開發環境

    buildroot上需要打開opencv,將其編譯進系統中,如下所示 測試可行性 測試是否編譯成功,通過獲取usb攝像頭的視頻來完成,本來是想通過qt的multimedia來實現,無奈k20300平臺
    發表于 08-27 15:08

    如何在FPGA中實現按鍵

    在FPGA(現場可編程門陣列)中實現按鍵是一個重要的設計環節,特別是在處理用戶輸入時,由于物理按鍵的機械特性和電氣特性,按鍵在按下和釋放的瞬間會產生抖動現象,這種抖動可能導致系統錯誤地識別為多次
    的頭像 發表于 08-19 18:15 ?3538次閱讀

    科研相機防技術-機身防和電子防

    ? 機身防鏡頭昂貴的價格催生了機身防技術。機身防(即影像傳感器防)最早由KonicaMinolta提出,后來Sony收購了Ko
    的頭像 發表于 08-14 06:29 ?1019次閱讀
    科研相機防<b class='flag-5'>抖</b>技術-機身防<b class='flag-5'>抖</b>和電子防<b class='flag-5'>抖</b>