使用python讀取視頻中的指定數字(一):視頻分幀處理


寫在前面:

  一個做傳感器的朋友遇到了一個問題。他需要使用網絡分析儀做一些測試,但是這個網絡分析儀不能保存這些動態數據,以前采用的是這樣的方法:先用手機錄像,再用視頻編輯軟件一幀一幀的回放視頻,手動把數據抄下來,比較麻煩。因此我想嘗試用python寫一段小程序,代替人工操作。如圖是手機拍攝的視頻其中一張截圖,圖中的 433.03500 Mhz 就是我們需要的數據,它1s內會變化幾十次。

視頻截圖視頻截圖

  我的思路是先將視頻分幀提取成圖片,然后再識別數據,最后再保存。但是存在一個問題,視頻中存在很多不需要的數字和文字,如果全部提取出來就很不好分類。所以我打算將提取出的圖片分塊,保留需要的圖片塊。如下圖是整個流程的思維導圖。

流程思維導圖

  接下里就是各個部分的分別測試了,首先是視頻分幀。我采用的是opencv。

  安裝 opencv:打開 cmd 輸入

pip install opencv-python

  這里給出 opencv 的官方文檔鏈接:https://opencv-python-tutroals.readthedocs.io/en/latest/

  以下代碼是將指定視頻每一幀讀取並安順序命名保存,還是比較簡單的。調試過程中沒有遇到什么問題,就直接放在這里了。其中 frame 變量就是讀取出的圖片。需要將視頻和代碼放在一個文件夾下。

#視頻轉圖片
import cv2

video_path = 'test.mp4'  # 視頻地址
vid = cv2.VideoCapture(video_path)#打開視頻
n = 0

while vid.isOpened():
    is_read, frame = vid.read()
    if is_read:
        cv2.imwrite(str(n) + '.jpg', frame)
        cv2.waitKey(2)#輸出圖片
    else:
        break

  如果測試使用的視頻太長會導致程序會運行很久,我測試用的視頻只有6s,卻提取出了100多張圖片。所以在測試的時候可以加一些條件,比如每10幀截取一次圖片 等。這樣可以提高調試效率。

  在后面數字識別的時候我發現識別結果的准確率很低,查了一些資料並進行了一些 測試后,我發現將圖片變成黑白的可以很大的提高識別精度。這里使用到了 pillow 庫。至此還剩一個問題,opencv 讀出來的是 opencv 的圖片格式,pillow 庫使用 的是 img 格式,兩種格式並不一樣,所以這里需要小小的轉換一下。以下是將 opencv 讀取出的圖片變成灰度圖片並保存的代碼。

#提取視頻圖片並保存為黑白圖片
import cv2
import numpy
from PIL import Image

video_path = 'test_2.mp4'  # 視頻地址

vid = cv2.VideoCapture(video_path)#打開視頻
is_read, frame = vid.read()

if is_read:

    image_opencv = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
    image_org = Image.fromarray(image_opencv)
    image_org = image_org.convert('L')
    image_org.save('image_gray.jpg')#保存

    #以下代碼是把上面的四行簡寫成兩行了,最終程序這樣寫看起來會簡潔些
    #image_org = Image.fromarray(cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)).convert('L')
    #image_org.save('org.jpg')

print("原圖片尺寸為:\n" , image_org.size)

   這里我只保存了第一張的截圖。圖片效果如下。

視頻的第一張灰度截圖

  在后續的識別中還遇到了這樣一個問題,代碼會把其他不需要的數字識別出來,比如上圖的設備型號 E5071C 等等。這樣就導致后面數據不好處理。考慮到拍攝視頻的時候手機是固定不動的,視頻中需要識別的數據位置基本不會改變。所以我想直接手動截取需要的那一塊圖片,然后再去識別(方法有點笨 QAQ 我也沒辦法啦!)。因為之前已經變成 pillow 的 img 格式了,就直接使用 crop() 方法進行切割吧。

  具體使用方法是這樣的:因為截取的是一個矩形區域,只要確定左上角和右下角的兩個點的坐標,就能確定這個矩形區域的位置。在 crop(x1,y1,x2,y2) 中,這是兩個點的坐標,第一個是左上角的點,第二個是右下角的點。使用的時候自己觀察一下大概要截取哪一部分的圖片,修改這兩個點的坐標值就可以了。

  於是我就寫了一個小工具來確定這兩個坐標值。我將原尺寸的圖片和截取的圖片都保存下來,這樣就可以直接觀察截取的區間對不對了。這里還用到了下一部分的識別模塊,等下就講,那一句可以先注釋掉。只需要運行下面的代碼,看看截取的區間是否合適並且程序是否能識別就可以了。如果可以正確識別,我們就得到了這個合適的區間。

#確定區間的小工具
import cv2
import pytesseract
import numpy
from PIL import Image

name_of_result_file = 'result'#保存截圖結果的圖片文件名,可修改
name_of_frame_file = 'frame'#保存截圖結果的圖片文件名,可修改

box = (260, 880, 560, 1450)#數據,根據實際情況修改
result = ''#保存結果的字符串

video_path = 'test.mp4'  # 視頻地址
vid = cv2.VideoCapture(video_path)#打開視頻

is_read, frame = vid.read()
if is_read:

    image_org = Image.fromarray(cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)).convert('L')
    image_org.save('img_org.jpg')#原尺寸的圖片

    region = image_org.crop(box)#截取左邊的數字

   region.save('crop.jpg')
    result = pytesseract.image_to_string(region)#識別圖片

print(result)

  這個區間不太好確定,需要多試幾次,如下圖所示就得到了可使用的區間了。

 識別結果

 截取區間

  至此圖片處理部分就結束了。手動截取圖片區間的時候需要注意,區間不能太小,否則什么都識別不出來,具體原因我也不清楚。我多次測試發現這個區間並不好找,我覺得主要原因還是原視頻的清晰度不夠,導致截取出來的圖片很糊。我自己看起來都和馬賽克一樣,怎么讓程序處理呢。如果視頻比較清楚,那這個區間應當是很好找的。

轉載請注明出處: https://www.cnblogs.com/mysteriouspavilion/articles/15389927.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM