如何使用OpenCV为灰度数据应用colormap并输出彩色视频?
问题原因
你原来的代码生成的还是灰度视频,核心是这两个操作都没有真正应用伪彩映射:
cv2.COLOR_GRAY2BGR只是把单通道灰度图的数值复制到B、G、R三个通道,三个通道的数值完全相同,显示出来自然还是灰度效果- 注释掉的
cv2.merge逻辑和上面完全一致,也是三个通道同值,同样是灰度效果
两者都没有把不同的灰度值映射成不同的彩色组合,所以达不到你要的强化像素差异的效果。
解决方法
方法1:直接使用OpenCV内置的colormap(推荐,效率高)
OpenCV自带了cv2.applyColorMap函数可以直接完成灰度到伪彩的映射,内置就包含viridis方案,不需要额外依赖matplotlib,处理速度更快:
import cv2 import numpy as np # 假设gray_images是你原来的灰度数组,注意要先归一化到0-255的uint8格式 # 第一步:先把灰度图归一化到0-255 uint8范围(如果你的灰度值不是这个范围必须做这步) norm_gray = [cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U) for img in gray_images] color_images = [] for i in range(N): # 直接应用viridis colormap,得到的就是BGR三通道彩色图,直接可以写视频 color_img = cv2.applyColorMap(norm_gray[i], cv2.COLORMAP_VIRIDIS) color_images.append(color_img) # 后面写视频的逻辑可以直接复用你原来的代码,不需要改 out = cv2.VideoWriter("video.mp4", cv2.VideoWriter_fourcc(*'mp4v'), fps, (resolution[0], resolution[1]), 1) for img in color_images: out.write(img) out.release()
方法2:使用matplotlib的viridis colormap(和plt.imshow效果完全一致)
如果你需要和plt.imshow的显示效果100%对齐,可以用matplotlib的cm模块做映射,注意映射后要转成BGR格式适配OpenCV的写入逻辑:
import cv2 import numpy as np import matplotlib.cm as cm # 同样先把灰度值归一化到0-1范围,适配matplotlib的cmap输入要求 norm_gray = [cv2.normalize(img, None, 0, 1, cv2.NORM_MINMAX, dtype=cv2.CV_32F) for img in gray_images] color_images = [] for i in range(N): # 应用viridis cmap,得到的是RGBA四通道,范围0-1,转成0-255 uint8 rgba_img = cm.viridis(norm_gray[i]) rgb_img = np.uint8(rgba_img[...,:3] * 255) # matplotlib生成的是RGB顺序,OpenCV需要BGR顺序,做个通道转换 bgr_img = cv2.cvtColor(rgb_img, cv2.COLOR_RGB2BGR) color_images.append(bgr_img) # 后续写视频逻辑和上面一致 out = cv2.VideoWriter("video.mp4", cv2.VideoWriter_fourcc(*'mp4v'), fps, (resolution[0], resolution[1]), 1) for img in color_images: out.write(img) out.release()
注意事项
- 映射前必须保证灰度值范围适配:如果你的原始灰度图是0-1的浮点数、或者灰度值集中在很窄的区间,一定要先做归一化,否则colormap的色彩区分度会很差
- OpenCV的颜色通道顺序是BGR,matplotlib生成的是RGB,转换的时候不要搞反,否则颜色会出错
内容的提问来源于stack exchange,提问作者Raquel
相关产品推荐
相关产品推荐

