文章目錄
- 正文
- 附錄A:關于Python的錄屏方法總結(來自DeepSeek的回答)
- 1. 使用 `pyautogui` 和 `OpenCV` 錄制屏幕
- 2. 使用 `mss` 庫(高效屏幕捕獲)
- 3. 使用 `PIL.ImageGrab` 錄制屏幕
- 4. 使用 Windows 原生快捷鍵錄制(非 Python 方案)
- 5. 結合 GUI 實現錄屏工具(高級方案)
- 總結
- 附錄B:關于視頻格式轉換(以avi2mp4為例)
- 方法1:使用 `moviepy` 庫(推薦)
- 方法2:使用 `OpenCV` + `FFmpeg`
- 方法3:直接使用 `FFmpeg` 命令行(最高效)
- 方法4:使用 `PyAV`(高級控制)
- 常見問題解決
- 總結
正文
端午整個爛活。
龍舟爭渡2025
旗幟顏色的識別方法選了個最笨的,直接截取那塊,然后矩陣相減求F范數(二模),匹配差距最小的那個即可,因此需要提前把所有情況的截圖準備好,完整的圖片材料和演示視頻在https://github.com/caoyang-sufe/LongZhouZhengDu2025
目前速度不是特別快,但也基本夠用了。如果間隔取太小容易出錯,因為截屏速度跟不上。
# -*- coding: utf-8 -*-
# @author: caoyang
# @email: caoyang@stu.sufe.edu.cnimport cv2
import time
import numpy
import pyautoguifrom PIL import Image
from numpy.linalg import norm
from pynput.keyboard import Key, Controller as KeyController
from pynput.mouse import Button, Controller as MouseControllerimport numpy as npY1, Y2, X1, X2 = 200, 400, 830, 1090 # 這組參數適配1920×1080尺寸的屏幕jcolor_to_key = {'y': 'd', 'r': 'f', 'b': 'j', 'g': 'k'}def easy_show(image: numpy.ndarray, window_title: str="image") -> None:"""Show a image in a new window."""cv2.imshow(window_title,image)cv2.waitKey(0)cv2.destroyAllWindows()def get_screenshot():image = pyautogui.screenshot()image = cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)return imagedef load_labels():labels = dict()for color in "yrbg":for n in "12":image = Image.open(f"./temp/{color}{n}.png")image = cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)clipped_image = image[Y1: Y2, X1: X2, :]labels[f"{color}{n}"] = clipped_imagereturn labels# 判斷旗幟顏色及點擊次數
def classify_label(screenshot, labels):clipped_image = screenshot[Y1: Y2, X1: X2, :]diffs = {}for key, label in labels.items():diff = norm(label - clipped_image)diffs[key] = diffprint(diffs)predicted_label = min(diffs, key = lambda x: diffs[x])return predicted_labeldef run():keyboard_controller = KeyController()while True:screenshot = get_screenshot()labels = load_labels()predicted_label = classify_label(screenshot, labels)color = predicted_label[0]key_char = color_to_key[color]n = int(predicted_label[1])for _ in range(n):keyboard_controller.press(key_char)time.sleep(.05)keyboard_controller.release(key_char)time.sleep(.05)time.sleep(.1)time.sleep(2)
run()
爛活完了順便延申一點,感覺錄屏還是有點問題,cv2.waitKey()
總是捕獲不到鍵位,之前就發現過這個問題,不知道怎么回事,問了一下deepseek,還是得用ffmpeg才行
附錄A:關于Python的錄屏方法總結(來自DeepSeek的回答)
1. 使用 pyautogui
和 OpenCV
錄制屏幕
這種方法通過不斷截取屏幕畫面并將其合成為視頻文件來實現錄屏。
import pyautogui
import cv2
import numpy as np# 設置錄屏參數
screen_size = pyautogui.size() # 獲取屏幕分辨率
fps = 30.0
output_file = "screen_recording.avi"# 創建視頻編碼器
fourcc = cv2.VideoWriter_fourcc(*"XVID")
out = cv2.VideoWriter(output_file, fourcc, fps, screen_size)# 開始錄屏
while True:img = pyautogui.screenshot() # 截取屏幕frame = np.array(img)frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) # 轉換顏色格式out.write(frame) # 寫入視頻文件# 按下 'q' 鍵停止錄制if cv2.waitKey(1) == ord('q'):break# 釋放資源
out.release()
cv2.destroyAllWindows()
優點:簡單易用,適合基礎錄屏需求。
缺點:性能較低,可能在高分辨率或高幀率下卡頓。
2. 使用 mss
庫(高效屏幕捕獲)
mss
是一個高效的跨平臺屏幕捕獲庫,適合高性能錄屏。
import mss
import cv2
import numpy as npdef record_screen(output_filename="output.avi", fps=20.0):with mss.mss() as sct:monitor = sct.monitors[1] # 獲取主屏幕fourcc = cv2.VideoWriter_fourcc(*"XVID")out = cv2.VideoWriter(output_filename, fourcc, fps, (monitor["width"], monitor["height"]))while True:img = np.array(sct.grab(monitor)) # 捕獲屏幕frame = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR) # 轉換顏色格式out.write(frame) # 寫入視頻文件# 按下 'q' 鍵停止錄制if cv2.waitKey(1) & 0xFF == ord("q"):breakout.release()cv2.destroyAllWindows()if __name__ == "__main__":record_screen()
優點:性能較好,支持多顯示器。
缺點:需要額外安裝 mss
庫。
3. 使用 PIL.ImageGrab
錄制屏幕
PIL.ImageGrab
是 Python 圖像處理庫的一部分,適合簡單的屏幕捕獲。
from PIL import ImageGrab
import cv2
import numpy as npfps = 20
output_file = "recording.avi"# 獲取屏幕尺寸
screen = ImageGrab.grab()
width, height = screen.size# 創建視頻編碼器
fourcc = cv2.VideoWriter_fourcc(*"XVID")
out = cv2.VideoWriter(output_file, fourcc, fps, (width, height))while True:img = ImageGrab.grab() # 捕獲屏幕frame = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR) # 轉換顏色格式out.write(frame) # 寫入視頻文件# 按下 'q' 鍵停止錄制if cv2.waitKey(1) == ord('q'):breakout.release()
cv2.destroyAllWindows()
優點:無需額外安裝復雜庫。
缺點:性能一般,不適合高幀率錄制。
4. 使用 Windows 原生快捷鍵錄制(非 Python 方案)
Win11 自帶錄屏功能:
- 按下
Win + Shift + S
可調用截圖和錄屏工具。 - 錄制完成后,可手動保存為 MP4 文件,再用 Python 轉換為 GIF(如使用
moviepy
庫)。
from moviepy.editor import VideoFileClipdef convert_mp4_to_gif(input_path, output_path, fps=10):clip = VideoFileClip(input_path)clip.write_gif(output_path, fps=fps)# 示例
convert_mp4_to_gif("input.mp4", "output.gif")
優點:無需編程,適合簡單需求。
缺點:依賴 Windows 自帶功能,靈活性較低。
5. 結合 GUI 實現錄屏工具(高級方案)
如果需要更友好的界面,可以結合 PyQt5
和 OpenCV
開發一個錄屏工具,支持開始/停止錄制、選擇區域等功能。
總結
方法 | 適用場景 | 性能 | 復雜度 |
---|---|---|---|
pyautogui + OpenCV | 基礎錄屏 | 較低 | 簡單 |
mss + OpenCV | 高性能錄屏 | 較高 | 中等 |
PIL.ImageGrab | 簡單錄屏 | 一般 | 簡單 |
Windows 原生錄屏 | 快速錄制 | 高 | 無需代碼 |
GUI 工具開發 | 自定義功能 | 高 | 復雜 |
選擇哪種方法取決于你的具體需求(如是否需要高幀率、是否要錄制音頻等)。如果需要更高級的功能(如音頻錄制),可以結合 pyaudio
庫實現。
附錄B:關于視頻格式轉換(以avi2mp4為例)
在Python中,你可以使用多種方法將AVI格式的視頻轉換為MP4格式。以下是幾種常見且高效的方式:
方法1:使用 moviepy
庫(推薦)
moviepy
是一個強大的視頻處理庫,適合簡單的格式轉換。
from moviepy.editor import VideoFileClipdef avi_to_mp4(input_path, output_path):# 加載AVI視頻video = VideoFileClip(input_path)# 寫入MP4文件(默認使用H.264編碼)video.write_videofile(output_path, codec="libx264", audio_codec="aac")# 關閉視頻對象video.close()# 示例
avi_to_mp4("input.avi", "output.mp4")
優點:
- 簡單易用,支持音頻保留。
- 自動處理編碼兼容性問題(默認使用H.264和AAC)。
安裝依賴:
pip install moviepy
方法2:使用 OpenCV
+ FFmpeg
如果已安裝FFmpeg,可以通過OpenCV調用FFmpeg進行轉換。
import cv2def avi_to_mp4_opencv(input_path, output_path):# 讀取AVI視頻cap = cv2.VideoCapture(input_path)# 獲取視頻參數(幀率、分辨率等)fps = cap.get(cv2.CAP_PROP_FPS)width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))# 創建MP4視頻寫入器(需FFmpeg支持)fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 或 'avc1'out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))# 逐幀轉換while cap.isOpened():ret, frame = cap.read()if not ret:breakout.write(frame)# 釋放資源cap.release()out.release()# 示例
avi_to_mp4_opencv("input.avi", "output.mp4")
注意:
- 確保系統已安裝FFmpeg(Windows用戶需下載并添加環境變量)。
- OpenCV的MP4編碼器(
mp4v
)可能在某些平臺兼容性較差,建議優先用moviepy
。
方法3:直接使用 FFmpeg
命令行(最高效)
如果追求轉換速度或處理大文件,直接調用FFmpeg命令行是最佳選擇。
import subprocessdef avi_to_mp4_ffmpeg(input_path, output_path):command = ['ffmpeg','-i', input_path, # 輸入文件'-c:v', 'libx264', # H.264視頻編碼'-c:a', 'aac', # AAC音頻編碼'-strict', 'experimental','-y', # 覆蓋輸出文件output_path]subprocess.run(command)# 示例
avi_to_mp4_ffmpeg("input.avi", "output.mp4")
優點:
- 轉換速度最快,支持所有主流編碼。
- 可自定義參數(如分辨率、比特率等)。
安裝FFmpeg:
- Windows:從 FFmpeg官網 下載并添加至系統環境變量。
- macOS:
brew install ffmpeg
- Linux:
sudo apt install ffmpeg
方法4:使用 PyAV
(高級控制)
PyAV
是FFmpeg的Python綁定,適合需要精細控制編碼參數的場景。
import avdef avi_to_mp4_pyav(input_path, output_path):input_container = av.open(input_path)output_container = av.open(output_path, mode='w')# 配置輸出流(復制輸入流的參數)in_stream = input_container.streams.video[0]out_stream = output_container.add_stream('h264', rate=in_stream.average_rate)out_stream.width = in_stream.widthout_stream.height = in_stream.height# 逐幀轉碼for frame in input_container.decode(video=0):packet = out_stream.encode(frame)output_container.mux(packet)# 關閉容器output_container.close()input_container.close()# 示例
avi_to_mp4_pyav("input.avi", "output.mp4")
優點:
- 支持底層編碼參數調整。
- 性能接近原生FFmpeg。
安裝依賴:
pip install av
常見問題解決
-
轉換后無聲音:
- 確保使用支持音頻的編碼器(如
moviepy
或FFmpeg的-c:a aac
)。 - 檢查輸入文件是否包含音頻流(可用
ffmpeg -i input.avi
查看)。
- 確保使用支持音頻的編碼器(如
-
轉換速度慢:
- 使用FFmpeg命令行并添加
-preset fast
參數。 - 降低輸出分辨率(如
-vf scale=1280:720
)。
- 使用FFmpeg命令行并添加
-
文件體積過大:
- 調整比特率(如
-b:v 2000k
)。 - 使用CRF控制質量(如
-crf 23
,數值越小質量越高)。
- 調整比特率(如
總結
方法 | 適用場景 | 是否需要FFmpeg | 保留音頻 |
---|---|---|---|
moviepy | 快速簡單轉換 | 否 | 是 |
OpenCV + FFmpeg | 需要逐幀處理 | 是 | 可選 |
FFmpeg命令行 | 高性能/批量處理 | 是 | 是 |
PyAV | 高級編碼控制 | 是 | 是 |
推薦選擇:
- 普通用戶:直接用
moviepy
。 - 開發者或需要批量處理:FFmpeg命令行。