Python使用OpenCV全屏播放视频时如何修改imshow的pillarbox颜色
OpenCV全屏播放修改pillarbox填充色方案
OpenCV 官方的 HighGUI 交互模块没有提供修改自动填充区域默认灰色的公开配置项,这个侧边灰边是不同GUI后端(Win32/GTK/Qt等)硬编码的默认窗口背景色,没有对外暴露修改入口。
最通用、兼容性最好的实现方式是自行绘制填充背景,完全绕开OpenCV的自动填充逻辑:
- 提前获取显示器全屏状态下的实际分辨率
- 按照视频原始4:3宽高比,计算视频帧在屏幕上等比例缩放后的尺寸,保证画面不拉伸变形
- 先创建和屏幕分辨率完全一致的纯色底图,颜色可以自定义
- 把缩放后的视频帧绘制到底图正中间,将合成好的完整画面传给
imshow即可,此时画面占满整个屏幕,不会出现系统默认的灰色填充区
你原来的代码存在一个小问题:窗口创建、全屏设置的逻辑写在了播放循环里,会反复触发窗口重绘导致不必要的性能消耗和画面抖动,这部分逻辑移到循环外只执行一次即可。
修正后可直接运行的参考代码:
#!/usr/bin/env python3 import cv2 as cv # 自定义填充色,注意OpenCV默认颜色顺序为BGR,比如纯黑填(0,0,0),纯蓝填(255,0,0) FILL_COLOR = (0, 0, 0) cap = cv.VideoCapture("video.mp4") # 窗口初始化、全屏设置仅执行一次 cv.namedWindow("video", cv.WINDOW_NORMAL) cv.setWindowProperty("video", cv.WND_PROP_FULLSCREEN, cv.WINDOW_FULLSCREEN) # 触发一次窗口渲染,拿到当前屏幕的实际宽高 ret, first_frame = cap.read() cv.imshow("video", first_frame) cv.waitKey(1) _, _, screen_w, screen_h = cv.getWindowImageRect("video") # 计算4:3视频等比例缩放到屏幕上的尺寸,保证画面不变形 VIDEO_ASPECT_RATIO = 4 / 3 SCREEN_ASPECT_RATIO = screen_w / screen_h if SCREEN_ASPECT_RATIO > VIDEO_ASPECT_RATIO: # 屏幕宽高比更大,视频高度撑满屏幕,左右留自定义填充 render_h = screen_h render_w = int(render_h * VIDEO_ASPECT_RATIO) else: # 屏幕高宽比更大,视频宽度撑满屏幕,上下留自定义填充 render_w = screen_w render_h = int(render_w / VIDEO_ASPECT_RATIO) # 计算视频帧居中放置的坐标偏移 x_offset = (screen_w - render_w) // 2 y_offset = (screen_h - render_h) // 2 while cap.isOpened(): ret, frame = cap.read() if not ret: break # 缩放视频帧到适配尺寸 resized_frame = cv.resize(frame, (render_w, render_h)) # 给视频帧加上自定义颜色的边框,直接生成和屏幕尺寸一致的完整画面 full_screen_frame = cv.copyMakeBorder( resized_frame, y_offset, screen_h - render_h - y_offset, x_offset, screen_w - render_w - x_offset, borderType=cv.BORDER_CONSTANT, value=FILL_COLOR ) cv.imshow("video", full_screen_frame) if cv.waitKey(10) & 0xFF == ord('q'): break cap.release() cv.destroyAllWindows()
补充说明:
- 如果你使用的OpenCV是带Qt后端编译的版本,理论上可以通过Qt样式接口修改窗口背景色,但这个方案依赖自定义编译选项,跨设备兼容性很差,不推荐使用。
- 修改
FILL_COLOR变量即可自由调整填充区域颜色,注意不要搞反BGR和RGB的颜色顺序,避免填充色和预期不一致。
内容的提问来源于stack exchange,提问作者dongle
相关产品推荐
相关产品推荐

