数据图像处理上机实验之颜色传输(OpenCv+Matlab+Python)

富士山系列图

        这个实验是目前我觉得在数字图像处理中很好玩的一个东西,在这里我推荐两篇论文,是介绍色彩传输有关的两种算法——Reinhard算法和Welsh算法。

论文链接:

Welsh:welsh.pdf (puc-rio.br)

Reinhard:ColorTransfer.pdf (tau.ac.il)

        既然你点开了这篇博客,相信你对这个也很感兴趣,下面话不多说,开始实验吧!!!

项目分析

本项目需要实现颜色传输,即将一个图像的颜色外观或色彩特性应用到另一个图像的过程。

本项目可分三个模块进行:

  1. 输入源图像以及目标图像,并将其从RGB空间转化到LAB空间
  2. 分别计算源图像以及目标图像在LAB空间各个维度的均值和方差
  3. 利用颜色传输的公式计算目标图像变换后的LAB值
  4. 将处理后的目标图像转化到RGB空间并输出图片。

计算公式:

项目流程

本项目我将采用三种方式实现:

——基于Matlab编程

        a. 利用Matlab内置库实现项目(rgb2lab(), lab2rgb());

        b. 手动编写RGBLAB空间互换的函数,不利用现有的库函数实现;

——基于Python编程

        a. 利用OpenCV第三方库实现项目(cv2.COLOR_BGR2LAB);

实验图像:

red.pngpur.pngsun.png

基于Matlab编程——Matlab内置库

  1. 利用imread函数读取目标图像’pur.png’和源图像’red.png’,并分别利用rgb2lab()函数将图像转化到LAB空间;
  2. 利用mean()函数和std()函数计算两个图像在LAB空间的均值和标准差;
  3. 利用for循环的方式遍历目标图像在LAB空间的每个值并利用颜色传输公式进行计算;
  4. 将处理后的图像使用lab2rgb()将其转化到RGB空间,使用imshow进行显示,利用imwrite进行图片的保存;

Matlab代码实现:

% 使用Matlab内置库完成项目
% 读取两个图像并将其转化为LAB模型
pur = imread('pur.png');
red = imread('red.png');
pur_lab = rgb2lab(pur);
red_lab = rgb2lab(red);
% 将pur图像作为目标图像,red图像作为传输颜色的源图像
% 计算pur的均值和标准差
pur_avg = mean(pur_lab, [1, 2]);
pur_std = std(pur_lab, 0, [1, 2]);
% 计算red的均值和标准差
red_avg = mean(red_lab, [1, 2]);
red_std = std(red_lab, 0, [1, 2]);
% 获取目标图像的size大小
[height, width, channel] = size(pur_lab);
for i = 1 : height
    for j = 1 : width
        for k = 1 : channel
            t = pur_lab(i, j, k);
            % 转换公式
            t = (t - pur_avg(k)) * red_std(k) / pur_std(k) + red_avg(k);
            t = max(0, min(t, 255));
            pur_lab(i, j, k) = t;
        end
    end
end
result = lab2rgb(pur_lab);
imshow(result);
imwrite(result, 'result.png')

基于Matlab编程——手动实现RGBLAB空间的互换

——参考了很多资料和转化公式,太复杂了

(一)构建RGB转LAB空间的函数(无法实现直接转换,需借助XYZ空间)

  1. 构建Gamma函数,对读入的三个通道的分量分别做Gamma映射;
  2. 将映射后的三个分量作对应的矩阵运算,将RGB空间转换为XYZ空间;
  3. 构建Convert函数,将处理后的XYZ三通道的分量进行转化,实现XYZ空间转LAB空间;

注:参与函数的这些数字是查了很多资料在编写的,直接使用即可。

Gamma函数

% 构建Gamma函数
function res = Gamma(x)
    if x > 0.04045
        res = ((x + 0.055) / 1.055) .^ 2.4;
    else
        res = x / 12.92;
    end
end

 Convert函数

% 构建Convert函数
function res = Convert(x)
    if x > 0.008856
        res = x ^ (1 / 3);
    else
        res = 7.787 * x + 0.137931;
    end
end

RGB2LAB函数

% 手动实现RGB转LAB
function image = RGB2LAB(pur)
% 读取图像
pur_r = Gamma(double(pur(:, :, 1)) / 255.0);
pur_g = Gamma(double(pur(:, :, 2)) / 255.0);
pur_b = Gamma(double(pur(:, :, 3)) / 255.0);

% RBG 转 XYZ
pur_X = 0.412453 * pur_r + 0.357580 * pur_g + 0.180423 * pur_b;
pur_Y = 0.212671 * pur_r + 0.715160 * pur_g + 0.072169 * pur_b;
pur_Z = 0.019334 * pur_r + 0.119193 * pur_g + 0.950227 * pur_b;

% XYZ 转 LAB
pur_X = pur_X / 0.950456;
pur_Z = pur_Z / 1.088754;

fXTemp = Convert(pur_X);
fYTemp = Convert(pur_Y);
fZTemp = Convert(pur_Z);

L = 116 * fXTemp - 16;
A = 500 * (fXTemp - fYTemp);
B = 200 * (fYTemp - fZTemp);
image = cat(3, L, A, B);
end

(二)构建LABRGB函数(同样需要借助XYZ空间)

  1. 构建LAB2XYZ函数和辅助函数help_XYZ,利用转换公式将LAB三通道分量做相应的映射;
  2. 构建LAB2RGB函数和辅助函数help_RGB,对三通道分量进行处理,并将处理后的分量作矩阵运算以及Gamma映射;
  3. 利用cat函数将分量连接并输出;

LAB2XYZ函数

% 定义LAB 转 XYZ 的函数
function XYZ = LAB2XYZ(LAB)
    % 白色参考点 D65
    Xn = 0.95047;
    Yn = 1.00000;
    Zn = 1.08883;

    % LAB到XYZ的转换
    fY = (LAB(:, :, 1) + 16) / 116;
    fX = LAB(:, :, 2) / 500 + fY;
    fZ = fY - LAB(:, :, 3) / 200;

    X = Xn * help_XYZ(fX);
    Y = Yn * help_XYZ(fY);
    Z = Zn * help_XYZ(fZ);
    XYZ = cat(3, X, Y, Z);
end

help_XYZ函数

% 定义LAB 转 XYZ 的辅助函数
function res = help_XYZ(t)
    delta = 0.008856;
    if t > delta
        res = t .^3;
    else
        res = (t - 0.137931) / 7.787;
    end
end

LAB2RGB函数

% 定义LAB 转 RGB 的函数
function RGB = LAB2RGB(LAB)
    % LAB到XYZ的转换
    XYZ = LAB2XYZ(LAB);
    
    X = XYZ(:, :, 1);
    Y = XYZ(:, :, 2);
    Z = XYZ(:, :, 3);
    
    % 进行gamma校正
    R = help_RGB( 3.2404542 * X - 1.5371385 * Y - 0.4985314 * Z);
    G = help_RGB(-0.9692660 * X + 1.8760108 * Y + 0.0415560 * Z);
    B = help_RGB( 0.0556434 * X - 0.2040259 * Y + 1.0572252 * Z);

    RGB = cat(3, R, G, B);
end

help_RGB函数

% 进行gama映射
function res = help_RGB(t)
    delta = 0.0031308;
    if t <= delta
        res = t * 12.92;
    else
        res = 1.055  * t .^(1 / 2.4) -0.055;
    end
end

(三)利用自定义的RGB2LAB函数以及LAB2RGB函数实现

  1. imread函数读取目标图像’pur.png’和源图像’red.png’,并分别利用RGB2LAB()函数将图像转化到LAB空间;
  2. 利用mean()函数和std()函数计算两个图像在LAB空间的均值和标准差;
  3. 利用for循环的方式遍历目标图像在LAB空间的每个值并利用颜色传输公式进行计算;
  4. 将处理后的图像使用LAB2RGB()将其转化到RGB空间,使用imshow进行显示,利用imwrite进行图片的保存;

结果分析

        通过上述图片可以看到,两种方式均实现了颜色的传输,其中Matlab内置库处理之后的效果图更加柔和,并且亮度更高,手动处理的效果图存在亮度相对偏暗。

优化分析

        针对手动定义实现的颜色传输函数,初步分析是计算过程存在小数点的取舍问题,由于RGB和LAB互换的公式复杂并且要求的精度较高,函数执行过程中存在了小数点的取舍问题,导致L分量偏低,而L分量决定了图片的亮度信息,因此效果图偏暗

        计算过程涉及的小数点取舍问题不好控制,因此采用定义亮度提升函数将效果图进行一个亮度的提亮以及饱和度的优化。

enhance函数

function enhancedImage = enhance(image, brightnessFactor, saturationFactor)
    % brightnessFactor: 亮度提升因子(大于1表示提升,小于1表示降低)
    % saturationFactor: 饱和度提升因子(大于1表示提升,小于1表示降低)
    % 输出参数:
    % enhancedImage: 增强后的图像
    % 将 RGB 图像转换为 HSV 色彩空间
    hsvImage = rgb2hsv(image);
    % 提升亮度
    hsvImage(:, :, 3) = min(hsvImage(:, :, 3) * brightnessFactor, 1); % 限制亮度在 [0, 1] 范围内
    % 提升饱和度
    hsvImage(:, :, 2) = min(hsvImage(:, :, 2) * saturationFactor, 1); % 限制饱和度在 [0, 1] 范围内
    % 将增强后的 HSV 图像转换回 RGB 色彩空间
    enhancedImage = hsv2rgb(hsvImage);
end

 基于Python编程——OpenCv第三方库

  1. 通过cv2.imread()分别读取’sun.jpg’’red.png’图片,利用cv2.cvtColor()函数将两个图像均转换到LAB空间;
  2. 定义标准差和均值的计算函数并分别调用;
  3. 利用for循环的方式遍历目标图像在LAB空间的每个值并利用颜色传输公式进行计算;
  4. 通过cv2.cvtColor()将图像由LAB空间转化为RGB空间,使用cv2.imshow()显示,使用cv2.imwrite()写入
# 读取图片,将sun设置为目标图像
image = cv2.imread('sun.jpg')
image = cv2.cvtColor(image,cv2.COLOR_BGR2LAB)
# 将red设置欸源图像
original = cv2.imread('red.png')
original = cv2.cvtColor(original,cv2.COLOR_BGR2LAB)
 
# 定义计算标准差和均值函数
def getavgstd(image):
    avg = []
    std = []
    image_avg_l = np.mean(image[:,:,0])
    image_std_l = np.std(image[:,:,0])
    image_avg_a = np.mean(image[:,:,1])
    image_std_a = np.std(image[:,:,1])
    image_avg_b = np.mean(image[:,:,2])
    image_std_b = np.std(image[:,:,2])
    avg.append(image_avg_l)
    avg.append(image_avg_a)
    avg.append(image_avg_b)
    std.append(image_std_l)
    std.append(image_std_a)
    std.append(image_std_b)
    return (avg,std)
    
# 计算标准差和均值
image_avg,image_std = getavgstd(image)
original_avg,original_std = getavgstd(original)

# 对目标图像的每个lab分量值进行计算
height,width,channel = image.shape
for i in range(0,height):
    for j in range(0,width):
        for k in range(0,channel):
            t = image[i,j,k]
            t = (t-image_avg[k])*(original_std[k]/image_std[k]) + original_avg[k]
            t = 0 if t<0 else t
            t = 255 if t>255 else t
            image[i,j,k] = t

# 将图像转化到RGB空间
image = cv2.cvtColor(image,cv2.COLOR_LAB2BGR)
# 图片写入与显示
cv2.imwrite('sunset.png', image)
cv2.imshow('out', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

 分享就到这咯,如有错误,欢迎大家批评指正!!!

  • 24
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
PyCharm是一种集成开发环境(IDE),可以用于Python开发。Anaconda是一个Python发行版,包含了许多常用的科学计算库和工具。Python是一种通用的编程语言,常用于开发各种应用程序。OpenCV是一个开源的计算机视觉库,用于处理图像和视频数据。PyQt是Python的一个GUI库,用于创建图形用户界面。在上述引用中,提到了使用PyCharm和Anaconda来配置和管理PythonOpenCV和PyQt的开发环境。通过安装Anaconda,我们可以方便地使用其中的Python版本、OpenCV和PyQt库,而无需单独下载和配置它们。同时,PyCharm也可以与Anaconda集成,使得开发过程更加便捷。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [2020新版pycharm+anaconda+python+opencv+qt环境配置](https://download.csdn.net/download/weixin_38700430/13749822)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatgptT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [pycharm+anaconda+opencv+pyqt环境配置](https://blog.csdn.net/zong596568821xp/article/details/118028155)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatgptT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

施霁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值