OpenCV 提供了強大的影片處理能力,可以輕鬆讀取、顯示和處理影片檔案。結合 OpenAI 的視覺模型,可以自動生成每一幀的描述性註解,為影片分析和理解提供更豐富的資訊。此技術可用於自動生成影片摘要、內容標記、甚至是視障人士的輔助工具。透過 Python,可以將這些功能整合到一個完整的流程中,實作自動化的影片處理和註解生成。
import cv2
def display_video(file_name):
cap = cv2.VideoCapture(file_name)
if not cap.isOpened():
print("無法開啟影片")
return
while True:
ret, frame = cap.read()
if not ret:
break
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
收集影片資料集
程式首先收集影片資料集:
lfiles = [
"jogging1.mp4",
"jogging2.mp4",
"skiing1.mp4",
#...
"female_player_after_scoring.mp4",
"football1.mp4",
"football2.mp4",
"hockey1.mp4"
]
lf = len(lfiles)
for i in range(lf):
file_name = lfiles[i]
print("Collecting video", file_name)
print("Downloading video", file_name)
download_video(file_name)
輸出顯示下載的影片檔名:
Collecting video jogging1.mp4
Downloading video jogging1.mp4
Downloaded 'jogging1.mp4' successfully.
Collecting video jogging2.mp4
...
顯示影片縮圖
程式接著顯示每個影片的縮圖:
for i in range(lf):
file_name = lfiles[i]
video_capture.release()
display_video_frame(file_name, frame_number=5, size=(100, 110))
顯示每個影片的資訊和縮圖:
Displaying a frame of video: skiing1.mp4
Total number of frames: 58
Frame rate: 30.0
Video duration: 1.93 seconds
選擇和顯示影片
您可以選擇列表中的影片並顯示它:
file_name = "football1.mp4" # 輸入要顯示的影片檔名
# print("Displaying video: ", file_name)
內容解密:
上述程式碼使用 lfiles
列表儲存所有要下載和顯示的影片檔名。lf
變數儲存了列表中的影片數量。程式使用 for
迴圈迭代列表,下載每個影片並顯示其縮圖。display_video_frame
函式用於顯示每個影片的縮圖,該函式接受檔名、幀數和大小等引數。
圖表翻譯:
以下是程式的流程圖:
flowchart TD A[開始] --> B[收集影片資料集] B --> C[下載所有影片] C --> D[顯示每個影片的縮圖] D --> E[選擇和顯示影片] E --> F[結束]
這個流程圖展示了程式的主要步驟:收集影片資料集、下載所有影片、顯示每個影片的縮圖、選擇和顯示影片。
顯示影片
import cv2
def display_video(file_name):
# 讀取影片
cap = cv2.VideoCapture(file_name)
# 檢查影片是否開啟成功
if not cap.isOpened():
print("無法開啟影片")
return
# 讀取影片尺寸
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 顯示影片
while True:
ret, frame = cap.read()
if not ret:
break
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 釋放資源
cap.release()
cv2.destroyAllWindows()
內容解密:
上述程式碼定義了一個 display_video
函式,該函式用於顯示指設定檔名的影片。函式首先讀取影片,然後檢查影片是否開啟成功。如果開啟失敗,則印出錯誤訊息並傳回。如果開啟成功,則讀取影片的尺寸,並進入一個迴圈中不斷讀取影片的每一幀,並使用 OpenCV 的 imshow
函式顯示每一幀。當使用者按下 ‘q’ 鍵時,迴圈終止,資源被釋放。
圖表翻譯:
flowchart TD A[開始] --> B[讀取影片] B --> C[檢查影片是否開啟成功] C -->|成功| D[讀取影片尺寸] C -->|失敗| E[印出錯誤訊息] D --> F[顯示影片] F --> G[檢查是否按下 'q' 鍵] G -->|是| H[釋放資源] G -->|否| F
圖表翻譯:
此圖表描述了顯示影片的流程。首先,程式開始執行,然後讀取影片。如果影片開啟成功,則讀取影片的尺寸,並進入顯示影片的迴圈中。在迴圈中,程式不斷顯示每一幀,並檢查是否按下 ‘q’ 鍵。如果按下 ‘q’ 鍵,則迴圈終止,資源被釋放。如果沒有按下 ‘q’ 鍵,則繼續顯示下一幀。
影片處理技術
在進行影片分析之前,首先需要將影片下載並轉換為適合分析的格式。玄貓將使用一個名為 download_video
的函式來下載影片,這個函式位於 GitHub 子節點下的「安裝環境」章節中。
下載影片
下載功能是透過 download_video
函式實作的,這個函式會被玄貓呼叫。同時,display_video
函式的定義與前一節「AI 生成的影片資料集」中相同,負責顯示下載的影片。
def display_video(file_name):
# 以二進位制模式開啟檔案
with open(file_name, 'rb') as file:
# 讀取影片資料
video_data = file.read()
#...
# 傳回 HTML 物件
return HTML(html)
下載完成後,影片將被分割成單獨的幀。
分割影片為幀
split_file
函式用於從影片中提取幀,就像在前一節「AI 生成的影片資料集」中所定義的一樣。然而,在這裡,我們將擴充套件這個函式以儲存幀為 JPEG 檔案:
def split_file(file_name):
# 影片路徑
video_path = file_name
# 使用 OpenCV 讀取影片
cap = cv2.VideoCapture(video_path)
# 幀號
frame_number = 0
# 迴圈讀取影片幀
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
#...
這個過程使得影片被轉換成一系列的影像幀,方便進一步的分析和處理。
圖表翻譯:
flowchart TD A[下載影片] --> B[分割影片] B --> C[儲存幀為 JPEG] C --> D[進行分析]
在這個流程中,首先下載影片,然後分割影片成單獨的幀,最後儲存這些幀為 JPEG 檔案以便於後續分析。
使用 OpenCV 將影片分解為幀並儲存為 JPEG 影像
首先,我們使用 OpenCV 的 imwrite
函式將每一幀儲存為 JPEG 影像。這個過程涉及迭代影片中的每一幀,將其轉換為適合的格式,並使用 cv2.imwrite
將其儲存到磁碟中。
import cv2
# 假設 cap 是一個已經開啟的影片檔案
frame_number = 0
while True:
ret, frame = cap.read()
if not ret:
break
# 將每一幀儲存為 JPEG 影像
cv2.imwrite(f"frame_{frame_number}.jpg", frame)
frame_number += 1
print(f"Frame {frame_number} saved.")
cap.release()
Commentator:幫助生成幀的評論
在上一步驟中,我們已經將影片分解為單獨的幀。現在,Commentator 的工作是為每一幀生成評論。這個過程涉及三個主要的函式:
generate_openai_comments(filename)
: 詢問 GPT-4 視覺模型分析一幀並產生一個包含描述該幀的評論的回應。generate_comment(response_data)
: 從 GPT-4 視覺模型的回應中提取評論。save_comment(comment, frame_number, file_name)
: 將提取的評論儲存到一個 CSV 檔案中,該檔案的名稱與原始影片檔案相同。
提取評論函式
首先,我們定義 generate_comment
函式,以從 GPT-4 視覺模型的回應中提取相關資訊:
def generate_comment(response_data):
"""從 GPT-4 視覺模型的回應中提取相關資訊."""
try:
# 假設 response_data 中包含 'caption' 欄位
return response_data['caption']
except (KeyError, AttributeError):
print("錯誤:無法從回應中提取字幕.")
return "無法取得字幕."
儲存評論函式
接下來,我們定義 save_comment
函式,以將提取的評論儲存到一個 CSV 檔案中:
def save_comment(comment, frame_number, file_name):
"""將評論儲存到一個 CSV 檔案中."""
# 在檔案名稱後面追加 '.csv' 來建立完整的路徑
path = f"{file_name}.csv"
# 檢查檔案是否存在,以確定是否需要寫入檔頭
if not os.path.exists(path):
# 如果檔案不存在,建立它並寫入檔頭
with open(path, 'w', newline='') as csvfile:
fieldnames = ['frame_number', 'comment']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
# 將評論寫入 CSV 檔案
with open(path, 'a', newline='') as csvfile:
fieldnames = ['frame_number', 'comment']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writerow({'frame_number': frame_number, 'comment': comment})
圖表翻譯
此圖示
flowchart TD A[開始] --> B[讀取幀] B --> C[儲存幀為 JPEG] C --> D[生成評論] D --> E[儲存評論到 CSV] E --> F[結束]
圖表翻譯
此流程圖描述了從影片中提取幀、儲存為 JPEG 影像、生成評論並儲存評論到 CSV 檔案的整個過程。每一步驟都對應到上述程式碼中的特定部分,展示瞭如何使用 OpenCV 和 GPT-4 視覺模型實作這個功能。
使用Python和OpenAI視覺模型生成影片幀註解
簡介
本文將介紹如何使用Python和OpenAI視覺模型生成影片幀註解。這個程式包括從影片中抽取幀、使用OpenAI模型生成註解、並將註解儲存為CSV檔案,以便於後續的處理。
所需函式庫和模組
os
:用於作業系統相關功能,例如檢查檔案是否存在。csv
:用於讀寫CSV檔案。uuid
:用於生成唯一的ID。openai
:用於與OpenAI視覺模型互動,生成註解。
程式碼實作
import os
import csv
import uuid
import openai
# 定義影片幀路徑和CSV儲存路徑
video_folder = "/content"
csv_path = "comments.csv"
# 定義OpenAI模型引數
openai.api_key = "YOUR_OPENAI_API_KEY"
# 定義樣本頻率
nb = 3 # 樣本頻率
# 初始化計數器
counter = 0
# 取得總幀數
total_frames = len([file for file in os.listdir(video_folder) if file.startswith("frame_")])
# 開啟CSV檔案,若不存在則建立
write_header = not os.path.exists(csv_path)
with open(csv_path, 'a', newline='') as f:
writer = csv.writer(f, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
if write_header:
writer.writerow(['ID', 'FrameNumber', 'Comment', 'FileName'])
# 遍歷每一幀
for frame_number in range(total_frames):
counter += 1 # 增加計數器
# 檢查是否達到樣本頻率
if counter == nb and counter < total_frames:
counter = 0 # 重置計數器
# 組裝幀路徑
image_path = os.path.join(video_folder, f"frame_{frame_number}.jpg")
try:
# 使用OpenAI視覺模型生成註解
response = openai.Image.create(
image=open(image_path, "rb"),
prompt="Generate a comment for this image.",
n=1,
size="1024x1024"
)
comment = response["data"][0]["caption"]
# 生成唯一ID
unique_id = str(uuid.uuid4())
# 取得影片檔名
file_name = os.path.basename(video_folder)
# 寫入CSV檔案
writer.writerow([unique_id, frame_number, comment, file_name])
print(f"Analyzing frame {frame_number}... Done.")
except Exception as e:
print(f"Error processing frame {frame_number}: {e}")
註解和說明
- 本程式碼使用
openai
函式庫與OpenAI視覺模型互動,生成影片幀註解。 video_folder
變數定義了影片幀儲存的路徑,csv_path
變數定義了CSV檔案的儲存路徑。nb
變數控制樣本頻率,即每多少幀抽取一幀進行註解。- CSV檔案包含四列:
ID
(唯一ID)、FrameNumber
(幀號)、Comment
(註解)和FileName
(影片檔名)。 - 註解生成過程中,若遇到錯誤,會列印錯誤資訊並繼續處理下一幀。
圖表翻譯
flowchart TD A[開始] --> B[載入影片幀] B --> C[設定樣本頻率] C --> D[遍歷每一幀] D --> E{達到樣本頻率?} E -->|是|> F[使用OpenAI模型生成註解] E -->|否|> D F --> G[儲存註解至CSV] G --> H[完成]
圖表翻譯:
此流程圖描述了影片幀註解生成過程。首先載入影片幀,然後設定樣本頻率。接著遍歷每一幀,檢查是否達到樣本頻率。如果達到,則使用OpenAI模型生成註解,並儲存至CSV檔案。最後,完成註解生成過程。
影片評論系統:自動化評論生成與顯示
系統架構
影片評論系統由三個主要元件組成:Pipeline 1、Generator 和 Commentator。Pipeline 1 負責控制整個流程,Generator 則利用 OpenAI 的 ChatCompletion 生成評論,Commentator 負責顯示評論。
Generator
Generator 的主要功能是根據輸入的影片幀生成評論。以下是 Generator 的核心程式碼:
with open(image_path, "rb") as image_file:
image_data = image_file.read()
response = openai.ChatCompletion.create(
model="gpt-4-vision-preview",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "What is happening in this image?"},
{
"type": "image",
"image_url": f"data:image/jpeg;base64,{image_data}",
},
],
}
],
max_tokens=150,
)
Generator 利用 OpenAI 的 ChatCompletion 生成評論,傳入影片幀的影像資料和問題「What is happening in this image?」。
Commentator
Commentator 負責顯示評論。以下是 Commentator 的核心程式碼:
def display_comments(file_name):
path = f"{file_name}.csv"
df = pd.read_csv(path)
return df
Commentator 讀取 CSV 檔案並傳回包含評論的 DataFrame。
Pipeline 1 Controller
Pipeline 1 Controller 負責控制整個流程,包括呼叫 Generator 生成評論和 Commentator 顯示評論。以下是 Pipeline 1 Controller 的核心程式碼:
try:
# 呼叫 Generator 生成評論
comment = generate_comment(response)
save_comment(comment, frame_number, file_name)
except FileNotFoundError:
print(f"Error: Frame {frame_number} not found.")
except Exception as e:
print(f"Unexpected error: {e}")
Pipeline 1 Controller 呼叫 Generator 生成評論,然後呼叫 Commentator 顯示評論。
圖表翻譯
以下是 Mermaid 圖表,描述影片評論系統的流程:
flowchart TD A[Pipeline 1 Controller] --> B[Generator] B --> C[Commentator] C --> D[顯示評論] D --> E[傳回 DataFrame]
圖表翻譯
此圖表描述影片評論系統的流程。Pipeline 1 Controller 呼叫 Generator 生成評論,然後呼叫 Commentator 顯示評論。Commentator 讀取 CSV 檔案並傳回包含評論的 DataFrame。
影片處理控制器
控制器負責執行前三個步驟的工作,包括 Generator 和 Commentator。首先,它從第一步開始,選擇一個影片,下載它,並顯示它。在自動化管道中,這些功能可以分開。例如,一個指令碼可以迭代遍歷影片列表,自動選擇每一個,並封裝控制器功能。在這裡,我們將收集、下載和顯示影片,以便進行後續的處理。
import time
# 記錄開始時間
session_time = time.time()
# 步驟 1:顯示影片
print("步驟 1:收集影片")
file_name = "skiing1.mp4" # 輸入要處理的影片檔名
print(f"影片:{file_name}")
# 下載影片
print("步驟 1:從 GitHub 下載")
directory = "Chapter10/videos"
download(directory, file_name)
# 顯示影片
print("步驟 1:顯示影片")
display_video(file_name)
控制器接著將影片分割成幀,並對影片的幀進行評論:
# 步驟 2:分割影片
print("步驟 2:將影片分割成幀")
split_file(file_name)
然後,控制器啟動 Generator 來生成影片幀的評論:
內容解密:
session_time = time.time()
用於記錄程式執行的開始時間。file_name
變數用於儲存要處理的影片檔名。download(directory, file_name)
函式用於下載指定的影片檔案。display_video(file_name)
函式用於顯示下載的影片。split_file(file_name)
函式用於將影片分割成個別的幀,以便進行後續的評論生成。
圖表翻譯:
flowchart TD A[開始] --> B[收集影片] B --> C[下載影片] C --> D[顯示影片] D --> E[分割影片] E --> F[生成評論]
此流程圖描述了控制器執行的步驟,從收集影片到生成評論。每一步驟都對應到程式碼中的特定函式或操作。
步驟3:為影格新增註解
import time
import os
# 計時開始
start_time = time.time()
# 產生OpenAI註解
def generate_openai_comments(file_name):
# 在這裡實作OpenAI註解生成邏輯
pass
# 計算回應時間
response_time = time.time() - start_time
# 顯示影格數量
video_folder = "/content"
total_frames = len([file for file in os.listdir(video_folder) if file.endswith(".jpg")])
print(f"總影格數:{total_frames}")
# 顯示註解
def display_comments(file_name):
# 在這裡實作註解顯示邏輯
pass
# 計算總處理時間
total_time = time.time() - start_time
# 列印回應時間和總處理時間
print(f"回應時間:{response_time:.2f} 秒")
print(f"總處理時間:{total_time:.2f} 秒")
# 儲存註解和影格
save = True
save_frames = True
if save:
# 儲存註解為CSV格式
cpath = f"{file_name}.csv"
if os.path.exists(cpath):
# 將檔案複製到Google Drive
!cp {cpath} /content/drive/MyDrive/files/comments/{cpath}
print(f"檔案 {cpath} 複製成功。")
內容解密:
在這個步驟中,我們首先計算了開始時間,然後呼叫了 generate_openai_comments
函式來產生OpenAI註解。接下來,我們計算了回應時間和總處理時間。然後,我們顯示了影格數量和註解。最後,我們儲存了註解和影格。
圖表翻譯:
flowchart TD A[開始] --> B[產生OpenAI註解] B --> C[計算回應時間] C --> D[顯示影格數量] D --> E[顯示註解] E --> F[計算總處理時間] F --> G[儲存註解和影格]
圖表翻譯:
此圖表展示了步驟3的流程。首先,我們開始了流程,然後產生了OpenAI註解。接下來,我們計算了回應時間,然後顯示了影格數量和註解。最後,我們計算了總處理時間,然後儲存了註解和影格。
處理影片檔案和幀的儲存與刪除
在處理影片檔案時,經常需要將影片轉換為幀以進行進一步的分析或處理。以下是如何儲存和刪除這些檔案的步驟。
從技術架構視角來看,這個Python影片處理系統巧妙地整合了影片下載、幀提取、OpenAI視覺模型以及CSV儲存等多個模組。透過模組化的設計,系統有效地分離了各個功能,提升了程式碼的可維護性和擴充套件性。然而,目前系統的效能瓶頸可能在於OpenAI API的呼叫,尤其是在處理大量影片幀時,網路延遲和API呼叫頻率限制都可能影響整體處理速度。此外,系統的錯誤處理機制仍有待加強,例如在API呼叫失敗時,缺乏更完善的重試機制和錯誤記錄,可能導致資料遺失或處理中斷。對於重視處理效率的使用者,建議最佳化API呼叫策略,例如批次處理幀或採用非同步呼叫方式。未來,隨著邊緣運算技術的發展,可以預見部分AI模型推理將會遷移到本地端執行,從而降低對雲端API的依賴,進一步提升系統的效能和穩定性。對於追求高效能的應用場景,這將是一個值得關注的發展方向。玄貓認為,此係統架構具備良好的基礎,透過持續最佳化和整合新技術,將能更好地滿足日益增長的影片處理需求。