法线图的坐标系转换
乙巳正月廿四日,余察位姿、深度诸图,其制式各异,存法亦殊。尤甚者,法线图所载之向,或南辕北辙,不能相契。遂穷四十八变,逐一试之,终得正解。乃纂其法,录于下方,以资后学,博诸君一哂耳。
import os
import cv2
from itertools import permutations, product
def apply_channel_swap(img, swap_order):
"""
Apply channel swap to the image based on the given channel swap order.
swap_order should be a tuple of indices, e.g., (0, 1, 2) means no swap.
"""
return img[:, :, swap_order]
def invert_channel(img, channel_indices):
"""
Invert specific channels in the image (255 - value for the given channels).
channel_indices is a list of channel indices to be inverted (e.g., [0, 1] for R and G).
"""
img_copy = img.copy()
for channel in channel_indices:
img_copy[:, :, channel] = 255 - img_copy[:, :, channel]
return img_copy
# 读取A组和B组图像
base_path = '/media/Dataset/room'
A_path = os.path.join(base_path, 'normals_from_gm-prepare')
B_path = os.path.join(base_path, 'normals_from_pretrain')
img_name = '00000011.png'
A_img = cv2.imread(os.path.join(A_path, img_name))
B_img = cv2.imread(os.path.join(B_path, img_name))
# 获取所有通道交换组合
swap_orders = list(permutations([0, 1, 2]))
# 获取所有取反操作的组合
invert_combinations = list(product([False, True], repeat=3)) # 对每个通道是否取反
# 保存每种操作组合的结果
output_path = 'output'
os.makedirs(output_path, exist_ok=True)
for swap_order in swap_orders:
for invert_comb in invert_combinations:
# 应用通道交换
swapped_B_img = apply_channel_swap(B_img, swap_order)
# 根据取反操作选择要取反的通道
channels_to_invert = [i for i, invert in enumerate(invert_comb) if invert]
inverted_B_img = invert_channel(swapped_B_img, channels_to_invert)
# 生成操作名称字符串
swap_order_str = ''.join(['RGB'[x] for x in swap_order]) # e.g., 'RGB', 'RBG', etc.
invert_str = ''.join(['1' if invert else '0' for invert in invert_comb]) # e.g., '000', '010', etc.
adjusted_img_name = f"adjusted_B_{swap_order_str}_invert_{invert_str}.png"
# 保存调整后的法线图
cv2.imwrite(os.path.join(output_path, adjusted_img_name), inverted_B_img)
cv2.imwrite(os.path.join(output_path, "A.png"), A_img)