首页 > 解决方案 > 如何在 opencv-python 中将 EXR 图像与 jpg 图像合并?

问题描述

你好,我是一个游戏的纹理打包,想合并法线贴图的 R、G 通道、遮挡贴图(AO 和腔贴图的乘积,但是因为我不知道如何在 OpenCV 中乘以图像正确地,我只是使用腔贴图)和 EXR 中的置换贴图。法线和遮挡贴图是 JPEG,而位移是 EXR,所以我想合并它们,同时保持我认为的位深度。此外,我想以受支持的格式导出它,该格式既能保留位深度,又能与 UE4、Unity 等引擎兼容。这是我目前所得到的:

normal = cv2.imread('{subdir}/{code}_4K_Normal.jpg'.format(subdir=subdir, code=code), cv2.IMREAD_UNCHANGED)
ao = cv2.imread('{subdir}/{code}_4K_AO.jpg'.format(subdir=subdir, code=code), cv2.IMREAD_UNCHANGED)
cavity = cv2.imread('{subdir}/{code}_4K_Cavity.jpg'.format(subdir=subdir, code=code), cv2.IMREAD_UNCHANGED)
height = cv2.imread('{subdir}/{code}_4K_Displacement.exr'.format(subdir=subdir, code=code), cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)

normal_b, normal_g, normal_r = cv2.split(normal)
ao_b, ao_g, ao_r = cv2.split(ao)
cavity_b, cavity_g, cavity_r = cv2.split(cavity)
height_b, height_g, height_r = cv2.split(height)

noh = cv2.merge((cavity_r, normal_g, normal_r, height_r))

cv2.imwrite('{subdir}/{code}_4K_NOH_2.tga'.format(subdir=subdir, code=code), noh)

但是执行上述操作会给我这个错误:

noh = cv2.merge((cavity_r, normal_g, normal_r, height_r))
cv2.error: OpenCV(4.4.0) C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-h4wtvo23\opencv\modules\core\src\merge.dispatch.cpp:129: error: (-215:Assertion failed) mv[i].size == mv[0].size && mv[i].depth() == depth in function 'cv::merge'

所以这是我要问的问题:

  1. 我如何合并不同位深度的通道但仍保持高位深度。
  2. 将图像导出为适合游戏引擎的良好格式。

标签: pythonopencvimage-processingopencv-python

解决方案


我对 Unity 或 UE4 一无所知,所以如果有人更了解,请说,我会很乐意删除这些猜测/提示。

您尚未指定“高位深度”的含义- 每个样本可能是 15、16、31、32 或 64 位。请说清楚。

您似乎想要一个 4 通道 RGBA 输出文件。

因此,鉴于上述情况,我只能建议:

  • 如果每个样本 16 位或更少,可能会写一个 PNG,或者
  • 否则为 TIFF。

在合并它们之前,您需要确保所有通道的位深度相同。您可能还需要将它们缩放到足够亮,以便在其新的高位深度范围内可见。因此,如果您有来自 JPEG 的 8 位通道,并且您希望将其设为 16 位以与其他一些 16 位通道合并,请尝试:

HiDepthChannel = LoDepthChannel.astype(np.uint16)*256

推荐阅读