Python爬蟲新手進階版:怎樣讀取非結構化、圖像、視頻、語音數據
通過open讀取之後會返回一個圖像文件對象,後續所有的圖像處理都基於該對象進行。上述代碼執行後,通過 img.show() 會調用系統默認的圖像瀏覽器查看打開圖像進行查看。如圖所示。
該對象包含了很多方法可以用來打印輸出文件的屬性,例如尺寸、格式、色彩模式等。
print (‘img format: ‘, img.format) # 打印圖像格式
print (‘img size: ‘, img.size) # 打印圖像尺寸
print (‘img mode: ‘, img.mode) # 打印圖像色彩模式
上述代碼執行後返回的結果如下:
-
RGB:自然界中所有的顏色都幾乎可以用紅、綠、藍這三種顏色波長的不同強度組合得到,這種顏色模式在數字顯示領域非常流行。
-
CMYK:這是一種工業四色印刷的亞蘭瑟標準,四個字母分別指代青(Cyan)、洋紅(Magenta)、黃(Yellow)、黑(Black)。
-
HSB:這種模式使用色澤(Hue)、飽和度(Saturation)和亮度(Brightness)來表達顏色的要素,這種模式更多基於人類心理的認識和感覺。
-
其他模式:其他模式還包括灰度模式、索引模式、位圖模式等,也在一定場景下較為常見。
除此以外,基於該文件對象也可以進行其他操作,例如圖像格式轉換、旋轉、裁剪、合並、濾波處理、色彩處理、縮略圖處理等。限於篇幅,在此不作過多介紹。
2. 使用OpenCV讀取圖像
OpenCV讀取和展示圖像主要有兩類方法,第一種是使用cv庫,第二種是使用cv2庫。
第一種:使用cv讀取圖像
語法
cv2.imread(filename[, flags])
描述
讀取圖像內容,如果圖像無法讀取則返回空信息,支持圖像格式幾乎包括了日常所有場景下的格式,具體包括:
-
Windows bitmaps文件:*.bmp、*.dib
-
JPEG文件:*.jpeg、*.jpg、*.jpe
-
JPEG 2000文件:*.jp2
-
PNG文件:*.png
-
WebP文件:*.webp
-
移動圖像格式:*.pbm、*.pgm、*.ppm *.pxm、*.pnm
-
Sun rasters文件:*.sr、*.ras
-
TIFF 文件:*.tiff、*.tif
-
OpenEXR文件:*.exr
-
Radiance HDR文件:*.hdr、*.pic
參數
-
filename必填,字符串,圖像地址。
-
flags可選,int型或對應字符串,顏色的讀取模式。如果flag>0或者cv2.IMREAD_COLOR,讀取具有R/G/B三通道的彩色圖像;如果flag=0或cv2.IMREAD_GRAYSCALE,讀取灰度圖像;如果flag<0或cv2.IMREAD_UNCHANGED,讀取包含Alpha通道的原始圖像。
返回
圖像內容,如果圖像無法讀取則返回NULL。
提示:除了使用OpenCV自帶的圖像展示方法外,OpenCV還經常和matplotlib配合展示圖像,這種場景更加常用。組合使用時可借用Matplotlib的強大圖像展示能力進行圖像的對比和參照以及不同圖像模式的輸出。
03 讀取視頻數據
Python讀取視頻最常用的庫也是Opencv。本文以名為Megamind.avi的視頻為例進行說明,如下是一段讀取視頻內容的代碼示例:
import cv2 # 導入庫
cap = cv2.VideoCapture("tree.avi") # 獲得視頻對象
status = cap.isOpened() # 判斷文件知否正確打開
if status: # 如果正確打開,則獲得視頻的屬性信息
frame_width = cap.get(3) # 獲得幀寬度
frame_height = cap.get(4) # 獲得幀高度
frame_count = cap.get(7) # 獲得總幀數
frame_fps = cap.get(5) # 獲得幀速率
print (‘frame width: ‘, frame_width) # 打印輸出
print (‘frame height: ‘, frame_height) # 打印輸出
print (‘frame count: ‘, frame_count) # 打印輸出
print (‘frame fps: ‘, frame_fps) # 打印輸出
success, frame = cap.read() # 讀取視頻第一幀
while success: # 如果讀取狀態為True
cv2.imshow(‘vidoe frame‘, frame) # 展示幀圖像
success, frame = cap.read() # 獲取下一幀
k = cv2.waitKey(1000 / int(frame_fps)) # 每次幀播放延遲一定時間,同時等待輸入指令
if k == 27: # 如果等待期間檢測到按鍵ESC
break # 退出循環
cv2.destroyAllWindows() # 關閉所有窗口
cap.release() # 釋放視頻文件對象
上述代碼分為4個部分,以空行分隔。
第一部分為前3行,先導入庫,然後讀取視頻文件並獲得視頻對象,再獲得視頻讀取狀態。其中的關鍵方法是VideoCapture,用來讀取圖像。
語法
cv2.VideoCapture(VideoCapture ID|filename|apiPreference)
描述
讀取視頻設備或文件,並創建一個視頻對象實例
參數
必填,VideoCapture ID|filename
VideoCapture ID:int型,系統分配的設備對象的ID,默認的設備對象的ID為0。
Filename:
-
視頻文件的名稱,字符串,例如abc.avi。目前版本下只支持avi格式。
-
序列圖像,字符串,例如img_%2d.jpg(圖像序列包括img_00.jpg, img_01.jpg, img_02.jpg, ...)
-
視頻URL地址,字符串,例如protocol://host:port/script_name?script_params|auth
-
apiPreference:int型,後臺使用的API
返回
一個視頻對象實例
第二部分為if循環體內的9行代碼,該代碼主要用來在判斷文件被正確讀取的情況下,輸出視頻文件的整體信息。除了代碼中get方法使用的參數值外,OpenCV還支持更多圖像屬性,如下表所示。
值 |
屬性 |
描述 |
0 |
CV_CAP_PROP_POS_MSEC |
當前位置(單位:ms) |
1 |
CV_CAP_PROP_POS_FRAMES |
當前位置(單位:幀數,從0開始計) |
2 |
CV_CAP_PROP_POS_AVI_RATIO |
當前位置(單位:比率, 0表示開始,1表示結尾) |
3 |
CV_CAP_PROP_FRAME_WIDTH |
幀寬度 |
4 |
CV_CAP_PROP_FRAME_HEIGHT |
幀高度 |
5 |
CV_CAP_PROP_FPS |
幀速率 |
6 |
CV_CAP_PROP_FOURCC |
4-字符表示的視頻編碼(如:’M‘, ’J‘, ’P‘,’G‘) |
7 |
CV_CAP_PROP_FRAME_COUNT |
總幀數 |
8 |
CV_CAP_PROP_FORMAT |
retrieve().調用返回的矩陣格式 |
9 |
CV_CAP_PROP_MODE |
後端變量指示的當前捕獲的模式 |
10 |
CV_CAP_PROP_BRIGHTNESS |
明亮度(僅用於攝像頭) |
11 |
CV_CAP_PROP_CONTRAST |
對比度(僅用於攝像頭) |
12 |
CV_CAP_PROP_SATURATION |
飽和度(僅用於攝像頭) |
13 |
CV_CAP_PROP_HUE |
色調(僅用於攝像頭) |
14 |
CV_CAP_PROP_GAIN |
增益(僅用於攝像頭) |
15 |
CV_CAP_PROP_EXPOSURE |
曝光度 (僅用於攝像頭) |
16 |
CV_CAP_PROP_CONVERT_RGB |
是否應該將圖像轉化為RGB圖像(布爾值) |
17 |
CV_CAP_PROP_WHITE_BALANCE |
白平衡(暫不支持 v2.4.3) |
▲get方法支持的圖像屬性
第三部分為具體讀取和展示視頻的每一幀內容。首先讀取視頻的第一幀,如果狀態為True,則展示圖像並讀取下一幀,期間通過cv2.waitKey參數做圖像延遲控制,同時延遲期間等待系統輸入指定,如果有輸入ESC則退出循環讀取幀內容。
第四部分為當所有操作結束後,刪除所有由OpenCv創建的窗體,釋放視頻文件對象。
有關OpenCV的更多信息,具體查閱opencv.org
04 讀取語音數據
對於語音文件的讀取,可以使用Python的audioop、aifc、wav等庫實現。但針對語音處理這一細分領域,當前市場上已經具備非常成熟的解決方案,例如科大訊飛、百度語音等,大多數情況下,我們會通過調用其API實現語音分析處理的功能,或者作為分析處理前的預處理功能。
在具體實現過程中,既可以直接下載SDK做離線應用,也可以使用在線的服務。
本文將以百度語音API服務應用為例,說明如何通過請求百度語音的API,將語音數據轉換為文字信息。
在正式應用百度語音API之前,請先建立百度賬戶以及註冊成為百度開發者。
基於該條件下,我們繼續開通語音識別服務。具體方法如下:
進入http://yuyin.baidu.com/app,在彈出的界面中點擊要針對哪個應用開通語音識別服務。我們默認使用在之前建立的API_For_Python應用中。因此,點擊該應用的“開通服務”。
▲開通服務
在彈出的窗口中,點擊選擇“語音識別”並確定。
▲選擇開通語音識別服務
開通成功後系統會提示“服務已開通”,然後點擊右側的“查看key”,會彈出如下信息:
▲圖2-32 應用key信息
上述彈出中的API Key和Secret Key為在後續語音識別中要使用的信息。
以下為完整代碼:
# 導入庫
import json # 用來轉換JSON字符串
import base64 # 用來做語音文件的Base64編碼
import requests # 用來發送服務器請求
# 獲得token
API_Key = ‘DdOyOKo0VZBgdDFQnyhINKYDGkzBkuQr‘ # 從申請應用的key信息中獲得
Secret_Key = ‘oiIboc5uLLUmUMPws3m0LUwb00HQidPx‘ # 從申請應用的key信息中獲得
token_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s" # 獲得token的地址
res = requests.get(token_url % (API_Key, Secret_Key)) # 發送請求
res_text = res.text # 獲得請求中的文字信息
token = json.loads(res_text)[‘access_token‘] # 提取token信息
# 定義要發送的語音
voice_file = ‘baidu_voice_test.pcm‘ # 要識別的語音文件
voice_fn = open(voice_file, ‘rb‘) # 以二進制的方式打開文件
org_voice_data = voice_fn.read() # 讀取文件內容
org_voice_len = len(org_voice_data) # 獲得文件長度
base64_voice_data = base64.b64encode(org_voice_data) # 將語音內容轉換為base64編碼格式
# 發送信息
# 定義要發送的數據主體信息
headers = {‘content-type‘: ‘application/json‘} # 定義header信息
payload = {
"format": "pcm", # 以具體要識別的語音擴展名為準
"rate": 8000, # 支持8000或16000兩種采樣率
"channel": 1, # 固定值,單聲道
"token": token, # 上述獲取的token
"cuid": "B8-76-3F-41-3E-2B", # 本機的MAC地址或設備唯一識別標誌
"len": org_voice_len, # 上述獲取的原始文件內容長度
"speech": base64_voice_data # 轉碼後的語音數據
}
data = json.dumps(payload) # 將數據轉換為JSON格式
vop_url = ‘http://vop.baidu.com/server_api‘ # 語音識別的API
voice_res = requests.post(vop_url, data=data, headers=headers) # 發送語音識別請求
api_data = voice_res.text # 獲得語音識別文字返回結果
text_data = json.loads(api_data)[‘result‘]
print (api_data) # 打印輸出整體返回結果
print (text_data) # 打印輸出語音識別的文字
代碼以空行作為分隔,包括4個部分:
第一部分為導入需要的庫信息,具體用途見代碼註解。
第二部分為獲得要使用百度語音識別API的token信息。其中的API_Key和Secret_Key從“應用key信息”獲得。token_url通過占位符定義出完整字符串,並在請求時發送具體變量數據,從返回的信息中直接讀取token便於下面應用中使用。有關獲取token的更多信息,具體查閱http://yuyin.baidu.com/docs/asr/56。
提示:在請求獲取token時,可使用get或post(推薦使用)兩種方法,Token的有效期默認為1個月,如果過期需要重新申請。
第三部分主要用於獲取和處理語音文件數據。通過最常見的open方法以二進制的方式讀取語音數據,然後從獲得的語音數據中獲取原始數據長度並將原始數據轉換為base64編碼格式。
註意:百度語音識別API對於要識別的音頻源是有要求的:原始 PCM 的錄音參數必須符合 8k/16k 采樣率、16bit 位深、單聲道,支持的壓縮格式有:pcm(不壓縮)、wav、opus、amr、x-flac。
第四部分為本節內容的主體,發送請求獲取語音識別結果。本段落中先定義了發送頭信息;然後定義了一個字典,用於存儲要發送的key-value字符串並將其轉換為json格式;接著通過post方法以隱示發送的方式進行上傳並獲得返回結果,最後輸出返回結果和其中的語音轉文字的信息。該部分內容的細節比較多,具體參見百度語音API開發說明http://yuyin.baidu.com/docs/asr/57。
關於cuid的獲取,由於筆者是在本地電腦上測試的,因此使用的是MAC地址。獲取MAC地址的方法是:打開系統終端命令行窗口(Win+R,輸入cmd並回車),在命令行中輸入命令ipconfig/all,在列出的所有連接中找到其中媒體狀態不是“媒體已斷開”並且屬於當前連接的物理地址信息,如下圖為筆者電腦MAC信息:
▲獲取MAC地址信息
有關語音服務的更多信息,具體查閱http://www.xfyun.cn/。
上述代碼執行後返回如下結果:
{"corpus_no":"6409809149574448654","err_msg":"success.","err_no":0,"result":["百度語音提供技術支持,"],"sn":"83327679891492399988"}
[u‘\u767e\u5ea6\u8bed\u97f3\u63d0\u4f9b\u6280\u672f\u652f\u6301\uff0c‘]
系統成功返回是識別結果,錄音的內容是“百度語音提供技術支持”,第二端的編碼是unicode編碼格式的中文。
總結:上述語音識別僅提供了關於語音轉文字的方法,其實語音本身包括非常多的信息,除了相對淺層的生理和物理特征,例如語速、音調、音長、音色、音強等外;還包括更深層次的社會屬性,這部分內容需要自然語音理解的深層次應用。目前的語音數據讀取後主要應用方向包括:
-
語音轉文字。這也是廣義上語音識別的一種,直接將語音信息轉為文字信息,例如微信中就有這個小功能。
-
語音識別。語音識別指的是對說話者通過選取語音識別單元、提取語音特征參數、模型訓練、模型匹配等階段實現其角色識別和個體識別的過程,例如通過某段語音識別出是哪個人說的話。
-
語音語義理解。在語音識別的基礎上,需要對語義特征進行分析,目的是通過計算得到語音對應的潛在知識或意圖,然後提供對應的響應內容或方法。語音識別和語音理解的差異之處在於,語音識別重在確定語音表達的字面含義,屬於表層意義;而語音理解重在挖掘語音的背後含義,屬於深層意義。
-
語音合成。語音合成就是讓計算機能夠“開口說話”,這是一種擬人的技術方法。語音合成,又稱文本轉語音(Text to Speech)技術,它通過機械的、電子的方法將文字信息轉變為人類可以聽得懂的語音。
-
應用集成。經過分析、識別後的信息可以與硬件集成,直接通過語音發送指令。例如通過跟Siri的“溝通”,除了可以進行日常溝通,它還可以告訴你天氣情況、幫你設置系統日程、介紹餐廳等。這是智能機器人在模式識別方面的典型應用。
基於上述的復雜應用場景,通常語音後續分析、處理和建模等過程都無法由數據工程師單獨完成,還需要大量的語料庫素材、社會學、信號工程、語言語法、語音學、自然語音處理、機器學習、知識搜索、知識處理等交叉學科和相關領域才有可能解開其中的密碼。
也歡迎大家關註我的博客:https://home.cnblogs.com/u/sm123456/
歡迎大家加入千人交流答疑群:125240963Python爬蟲新手進階版:怎樣讀取非結構化、圖像、視頻、語音數據