python - XYZ/RGB 中的颜色校正矩阵不起作用
问题描述
我的目标是使用颜色图表根据参考图像执行颜色校正。作为个人目标,我正在尝试纠正我之前修改过的图像的颜色。当然,图表也受到相同层的影响:
原件:
手动修改:
我正在使用我自己编写的以下函数来获取矩阵:
def _get_matrix_transformation(self,
observed_colors: np.ndarray,
reference_colors: np.ndarray):
"""
Args:
observed_colors: colors found in target chart
reference_colors: colors found on source/reference image
Returns:
Nothing.
"""
# case 1
observed_m = [observed_colors[..., i].mean() for i in range(observed_colors.shape[-1])]
observed_colors = (observed_colors - observed_m).astype(np.float32)
reference_m = [reference_colors[..., i].mean() for i in range(reference_colors.shape[-1])]
reference_colors = (reference_colors - reference_m).astype(np.float32)
# XYZ color conversion
observed_XYZ = cv.cvtColor(observed_colors, cv.COLOR_BGR2XYZ)
observed_XYZ = np.reshape(observed_colors, (observed_XYZ.shape[0] * observed_XYZ.shape[1],
observed_XYZ.shape[2]))
reference_XYZ = cv.cvtColor(reference_colors, cv.COLOR_BGR2XYZ)
reference_XYZ = np.reshape(reference_colors, (reference_XYZ.shape[0] * reference_XYZ.shape[1],
reference_XYZ.shape[2]))
# case 2
# mean subtraction in order to use the covariance matrix
# observed_m = [observed_XYZ[..., i].mean() for i in range(observed_XYZ.shape[-1])]
# observed_XYZ = observed_XYZ - observed_m
# reference_m = [reference_XYZ[..., i].mean() for i in range(reference_XYZ.shape[-1])]
# reference_XYZ = reference_XYZ - reference_m
# apply SVD
H = np.dot(reference_XYZ.T, observed_XYZ)
U, S, Vt = np.linalg.svd(H)
# get transformation
self._M = Vt.T * U.T
# consider reflection case
if np.linalg.det(self._M) < 0:
Vt[2, :] *= -1
self._M = Vt.T * U.T
return
我正在应用这样的更正:
def _apply_profile(self, img: np.ndarray) -> np.ndarray:
"""
Args:
img: image to be corrected.
Returns:
Corrected image.
"""
# Revert gamma compression
img = adjust_gamma(img, gamma=1/2.2)
# Apply color correction
corrected_img = cv.cvtColor(img.astype(np.float32), cv.COLOR_BGR2XYZ)
corrected_img = corrected_img.reshape((corrected_img.shape[0]*corrected_img.shape[1], corrected_img.shape[2]))
corrected_img = np.dot(self._M, corrected_img.T).T.reshape(img.shape)
corrected_img = cv.cvtColor(corrected_img.astype(np.float32), cv.COLOR_XYZ2BGR)
corrected_img = np.clip(corrected_img, 0, 255)
# Apply gamma
corrected_img = adjust_gamma(corrected_img.astype(np.uint8), gamma=2.2)
return corrected_img
如果在 BGR 中完成转换,我目前得到的结果(只是注释了颜色转换函数):
在 XYZ 中(不要注意调整大小,那是因为我):
现在,我在问这些问题:
- 在这种情况下是否需要反转伽马?如果是这样,我做得对吗?我应该实现一个与其他数据类型(如 np.float32)一起使用的 LUT 吗?
- 应在 BGR 颜色空间的 XYZ 中减去平均值(案例 1 与案例 2)?
- 是否需要考虑反射情况(如刚体旋转问题)?
- 剪裁有必要吗?如果是这样,这些是正确的值和数据类型吗?
解决方案
推荐阅读
- javascript - Javascript ES6 仅从文件夹中导入一些文件
- javascript - 在反应中同时访问两个状态
- azure - 如何在 Azure DevOps 中将构建版本与手动测试联系起来
- html - 在 as-pnet-core mvc 中渲染主体的问题
- javascript - 不明白为什么总是出现相同的文字?
- c - 为什么这个程序没有段错误显示?
- java - 出现错误:Webdriver 无法解析为类型,Chromedriver 无法解析为类型。请建议
- node.js - GRPC 目标方法无法解析。-@google-cloud/speech API
- java - 在 MapStruct 中抛出 noSuchMethodError
- python - 是否可以为 Python 中的一系列列替换特定的字符串?