颜色传输

2022-11-01 15:42:12 浏览数 (1)

问题

上图是一幅红色树林的图像,左下图是一个蔬菜的图像。

目标:将蔬菜图像的颜色组成换成树林图像的颜色组成。

要求:通过算法完成两个图像之间颜色的映射。

分析

下述出自论文**《图像处理中的颜色传递算法_李雅娜》**:

原文链接:图像处理中的颜色传递算法 - 中国知网 (cnki.net)

由于目前图像采用的颜色空间主要为 RGB 空间,但 RGB 颜色空间的各分量之间存在着相关性,这就意味着如果改变一个像素颜色外观的话,必须改变所有的颜色通道,这使得颜色更改过程变得极为复杂。而后 Ruderman 等人基于人类视觉对图像数据的感知研究,提出了lαβ 颜色空间,与 RGB 及其他颜色空间不同的是在 lαβ 颜色空间中通道间数据的相关性最小,从而可在不同的通道独立地进行统计信息的传递。

查阅论文,得知

故,我们需要的操作如下:

  1. 把源图片和目标图片由RGB转换为Lab颜色空间
  2. 分别两个计算各个通道的均值和方差,假设s_mean、t_mean、s_std、s_std 分别为源图像和目标图像Lab下某一通道的均值和方差
  3. 对源图像的每一通道的每个像素点作运算(设p为对应像素值):p = (p - s_mean) * (t_std / s_std) t_mean
  4. 把图像由Lab空间转换成RGB空间
  5. 对转换回的RGB图像作越界检测矫正处理

代码

代码语言:javascript复制
import numpy as np
import cv2
import os


def get_mean_and_std(x):
    # 计算矩阵的均值和标准差 以Mat形式返回
    x_mean, x_std = cv2.meanStdDev(x)
    # print(x_mean, x_std) 均为3*1的矩阵

    # 将矩阵进行连接 转换成 2*3的矩阵 方便操作
    x_mean = np.hstack(np.around(x_mean, 2))
    # print(x_mean)
    x_std = np.hstack(np.around(x_std, 2))
    # print(x_std)
    return x_mean, x_std

print("==读取源图片==")
s = cv2.imread('source.jpg')
s = cv2.cvtColor(s, cv2.COLOR_BGR2LAB)
print("==读取目标图片==")
t = cv2.imread('target.jpg')
t = cv2.cvtColor(t, cv2.COLOR_BGR2LAB)

print("==计算源图片的均值和标准差==")
s_mean, s_std = get_mean_and_std(s)
print("==计算目标图片的均值和标准差==")
t_mean, t_std = get_mean_and_std(t)

height, width, channel = s.shape
# print(height, width, channel)
# 385 383 3   (1*3)
for i in range(0, height):
    for j in range(0, width):
        for k in range(0, channel):
            x = s[i, j, k]
            # 归一化处理
            x = ((x-s_mean[k]) * (t_std[k] / s_std[k]))   t_mean[k]
            # 返回最接近的整数
            x = round(x)
            # 越界矫正
            x = 0 if x < 0 else x
            x = 255 if x > 255 else x
            s[i, j, k] = x

s = cv2.cvtColor(s, cv2.COLOR_LAB2BGR)
print("==保存转换好的图片==")
cv2.imwrite('result.jpg', s)

结果

0 人点赞