Photoshop入门学习之ISP模块之色彩增强算法--HSV空间Saturation通道调整
小标 2018-10-19 来源 : 阅读 1719 评论 0

摘要:本文主要向大家介绍了Photoshop入门学习之ISP模块之色彩增强算法--HSV空间Saturation通道调整,通过具体的内容向大家展现,希望对大家Photoshop入门学习有所帮助。

本文主要向大家介绍了Photoshop入门学习之ISP模块之色彩增强算法--HSV空间Saturation通道调整,通过具体的内容向大家展现,希望对大家Photoshop入门学习有所帮助。

 <

色彩增强不同于彩色图像增强,图像增强的一般处理方式为直方图均衡化等,目的是为了增强图像局部以及整体对比度。而色彩增强的目的是为了使的原有的不饱和的色彩信息变得饱和、丰富起来。对应于Photoshop里面的“色相/饱和度”调节选项里面对饱和度的操作。色彩增强的过程,并不改变原有彩色图像的颜色以及亮度信息。
    在我的色彩增强算法模块里面,始终只针对色彩饱和度(Saturation)信息做研究,调整。这样的话,那就不得不介绍HSV颜色空间了,H代表Hue(色彩),S代表Saturation(饱和度),V代表Value,也可用B表示(Brightness,明度),HSV空间也可称作HSB空间。
    HSV空间在wikipedia上的介绍,https://en.wikipedia.org/wiki/HSL_and_HSV 
    下面根据自己的理解介绍一下HSV空间,以及其各通道在Matlab和OpenCV中的不同。
    HSV的圆柱模型
     
    HSV的圆锥模型
     
    从上图可以看出,在HSV空间中,Hue通道的取值从0-360°变化时,颜色从红->黄->绿->青->蓝逐步变化。Saturation从0->1变化时,色彩逐渐加深变成纯色(pure)。Value值从0->1变化时,图像整体亮度增加,V值为0时,图像为全黑,V值为1时,图像为全白。
    Matlab RGB色彩空间向HSV转换,采用函数rgb2hsv,转换后的hsv各通道的元素取值范围为[0,1];OpenCV中彩色图像向HSV空间中转换,cvtColor(src,srcHsv,CV_BGR2HSV),转换后H的取值范围为[0,180],S,V的取值范围为[0,255].
   下面介绍自己的算法处理思路,后面会给出完整的Matlab代码: 
   步骤一、给出一张原图src,用PS进行饱和度(Saturation)+40处理后另存为src_40;
   步骤二、将以上两张图像分别转换到hsv空间,提取出饱和度信息,分别为S,S_40;
   步骤三、统计饱和度增加40后,原色彩饱和度与饱和度增量之间的对应关系,即S -- (S_40-S);
   步骤四、对关系S -- (S_40-S)进行二次多项式曲线拟合,得到二次曲线f(x) = p1*x^2 + p2*x + p3;
   为什么是二次?1.对应关系呈现出抛物线形状;2.更高次曲线并没有明显改善拟合性能,且计算消耗会变高。
   步骤五、任意给定输出图像input,根据其色彩饱和度信息,即可进行色彩增强40处理,新的饱和度信息可以表示为S‘(x) = S(x) + f(x),得到增强后的色彩信息后返回RGB图像输出;
   步骤六、分别对原图+20,+40,+60后进行饱和度信息统计,并得到相应拟合参数,设置为色彩增强的低、中、高三挡,在实际处理过程中,根据输入图像input自身色彩饱和度信息(均值)自适应选取相应参数进行色彩增强;
   步骤七、按需对某一单独颜色通道进行色彩增强处理,例如绿色范围为105°-135°,在对该范围进行增强的同时,还需对75°-105°,135°-165°进行一半强度的增强,这样才会保证色彩的连续性,不会出现色斑;
   步骤八、按需对色彩(Hue)进行转换;
   代码部分:第一部分用作估计拟合参数,在Curve fitting tool里面对X,Y进行拟合,得到曲线参数。
 


[plain] view plain copy print?


% Color Enhancement  
clc,clear,close all  
src1 = imread(‘src.bmp‘);  
src2 = imread(‘src_40.bmp‘);  
  
src1_hsv = rgb2hsv(src1);  
src2_hsv = rgb2hsv(src2);  
  
h1 = src1_hsv(:,:,1);  
s1 = src1_hsv(:,:,2);  
v1 = src1_hsv(:,:,3);  
  
h2 = src2_hsv(:,:,1);  
s2 = src2_hsv(:,:,2);  
v2 = src2_hsv(:,:,3);  
%   
meanS1 = mean(s1(:));  
varS1  = std2(s1);   
%   
meanS2 = mean(s2(:));  
varS2  = std2(s2);   
%   
deltaS = s2 - s1;  
deltaV = v2 - v1;  
  
%% test1 : 观测“原饱和度-饱和度调整增量”的关系 saturation and delta saturation  
figure;  
oriS = zeros(101,2);  
s3 = s1;  
j = 1;  
for i = 0: 0.01 : 1  
    oriS(j,1) = i + 0.01;  
    oriS(j,2) =  mean(deltaS(find(s1 > i & s1< i + 0.01)));  
    j = j + 1;  
end  
X  = oriS(:,1);  
Y  = oriS(:,2);  
XX = oriS(:,1) * 255;  
YY = oriS(:,2) * 255;  
plot(XX,YY)  

% Color Enhancement
clc,clear,close all
src1 = imread(‘src.bmp‘);
src2 = imread(‘src_40.bmp‘);

src1_hsv = rgb2hsv(src1);
src2_hsv = rgb2hsv(src2);

h1 = src1_hsv(:,:,1);
s1 = src1_hsv(:,:,2);
v1 = src1_hsv(:,:,3);

h2 = src2_hsv(:,:,1);
s2 = src2_hsv(:,:,2);
v2 = src2_hsv(:,:,3);

meanS1 = mean(s1(:));
varS1  = std2(s1); 

meanS2 = mean(s2(:));
varS2  = std2(s2); 

deltaS = s2 - s1;
deltaV = v2 - v1;

%% test1 : 观测“原饱和度-饱和度调整增量”的关系 saturation and delta saturation
figure;
oriS = zeros(101,2);
s3 = s1;
j = 1;
for i = 0: 0.01 : 1
    oriS(j,1) = i + 0.01;
    oriS(j,2) =  mean(deltaS(find(s1 > i & s1< i + 0.01)));
    j = j + 1;
end
X  = oriS(:,1);
Y  = oriS(:,2);
XX = oriS(:,1) * 255;
YY = oriS(:,2) * 255;
plot(XX,YY)
 
   第二部分,对输入图像进行高、中、低三级自适应增强处理
 


[html] view plain copy print?


%% Color Enhancement Module -- Authored by HuangDao,08/17/2015  
% functions: input a image of type BMP or PNG, the program will decide to  
% do the Color Enhancement choice for you.There are four types of Enhanced  
% intensity - 20,40,60,80.The larger number stands for stronger  
% enhancement.  
% And we can also choose the simple color channel(eg.R,G,B) to do the  
% enhancement.There are also four different types of enhanced intensity.  
%  
% parameters table  
%  ------------------------------------------------------------------------  
% | Enhanced  |     MATLAB params             |      OpenCV params         |  
% | intensity |p1        p2        p3         | p1        p2        p3     |  
% | 20        |-0.1661   0.2639    -0.003626  |-0.0006512 0.2639    -0.9246|  
% | 40        |-0.4025   0.6238    -0.0005937 |0.001578   0.6238    -0.1514|  
% | 60        |1.332     1.473     -0.01155   |-0.005222  1.473     -2.946 |  
% | 80        |-4.813    3.459     -0.004568  |-0.01887   3.459     -1.165 |  
%  ------------------------------------------------------------------------  
  
clc; clear ;close all  
% 载入文件夹  
pathName = ‘.\‘;  
fileType = ‘*.bmp‘;  
files    = dir([pathName fileType]);  
len      = length(files);  
  
for pic = 5%1:1:len  
    srcName = files(pic).name;  
    srcImg  = imread(srcName);  
    srcHSV  = rgb2hsv(srcImg);  
    srcH    = srcHSV(:,:,1);  
    srcS    = srcHSV(:,:,2);  
    srcV    = srcHSV(:,:,3);  
    meanS   = mean(srcS(:));  
    varS    = std2(srcS);  
    %图像整体进行色彩增强处理  
    if (meanS >= 0.5)  
        p1 = 0;p2 = 0;p3 = 0;  
    else if (meanS >= 0.35 && meanS < 0.5)  
            p1 = -0.1661;p2 = 0.2639;p3 = -0.003626;  
        else if (meanS >=0.2 && meanS <0.35)  
                p1 = -0.4025;p2 = 0.6238;p3 = -0.0005937;  
            else  
                p1 = 1.332;p2 = 1.473;p3 = -0.01155;  
            end  
        end  
    end  
    dstS = srcS + p1*srcS.*srcS + p2*srcS + p3 ;  
    dstHSV = srcHSV;  
    dstHSV(:,:,2) = dstS;  
    dstImg = hsv2rgb(dstHSV);  
    figure;imshow(srcImg);  
    figure;imshow(dstImg);  
    %指定R,G,B通道进行色彩增强处理,红色范围([225-255]),绿色范围(75-[105-135]-165),蓝色范围([-15-15])  
    p11 = -0.4025;p21 = 0.6238;p31 = -0.0005937;%周边杂色调整系数,40  
    p12 = 1.332;  p22 = 1.473; p32 = -0.01155;  %纯色区域调整系数,60  
    compHue = srcH;  
    GcompS  = dstS;  
    RcompS  = dstS;  
    BcompS  = dstS;  
    channel = ‘B‘;  
    switch channel  
        case ‘G‘  
            I1 = find(compHue > 0.2083 & compHue <0.2917);  
            GcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;  
            I2 = find(compHue >= 0.2917 & compHue <= 0.3750);  
            GcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;  
            I3 = find(compHue > 0.3750 & compHue <0.4583);  
            GcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;  
            compHSV = dstHSV;  
            compHSV(:,:,2) = GcompS;  
            dstImgG = hsv2rgb(compHSV);  
            figure;imshow(dstImgG);  
        case ‘R‘  
            I1 = find(compHue > 0.875 & compHue <0.9583);  
            RcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;  
            I2 = find(compHue >= 0.9583 | compHue <= 0.0417);  
            RcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;  
            I3 = find(compHue > 0.0417 & compHue <0.125);  
            RcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;  
            compHSV = dstHSV;  
            compHSV(:,:,2) = RcompS;  
            dstImgR = hsv2rgb(compHSV);  
            figure;imshow(dstImgR);  
        case ‘B‘  
            I1 = find(compHue > 0.5417 & compHue <0.625);  
            BcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;  
            I2 = find(compHue >= 0.625 & compHue <= 0.7083);  
            BcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;  
            I3 = find(compHue > 0.7083 & compHue <0.7917);  
            BcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;  
            compHSV = dstHSV;  
            compHSV(:,:,2) = BcompS;  
            dstImgB = hsv2rgb(compHSV);  
            figure;imshow(dstImgB);  
    end  
    %进行R,G,B通道之间的互换  
    convH = zeros(size(srcH,1),size(srcH,2)); %convert  
    deltaHue = 240;  
    switch deltaHue  
        case 120  
            disp(‘R -> G‘)  
            convH = srcH + 1/3;  
            convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;  
        case 240  
            disp(‘R -> B‘)  
            convH = srcH + 2/3;  
            convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;  
    end  
    convHSV = dstHSV;  
    convHSV(:,:,1) = convH;  
    convImg = hsv2rgb(convHSV);  
    figure;imshow(convImg)  
    pause();  
end  

%% Color Enhancement Module -- Authored by HuangDao,08/17/2015
% functions: input a image of type BMP or PNG, the program will decide to
% do the Color Enhancement choice for you.There are four types of Enhanced
% intensity - 20,40,60,80.The larger number stands for stronger
% enhancement.
% And we can also choose the simple color channel(eg.R,G,B) to do the
% enhancement.There are also four different types of enhanced intensity.
%
% parameters table
%  ------------------------------------------------------------------------
% | Enhanced  |     MATLAB params             |      OpenCV params         |
% | intensity |p1        p2        p3         | p1        p2        p3     |
% | 20        |-0.1661   0.2639    -0.003626  |-0.0006512 0.2639    -0.9246|
% | 40        |-0.4025   0.6238    -0.0005937 |0.001578   0.6238    -0.1514|
% | 60        |1.332     1.473     -0.01155   |-0.005222  1.473     -2.946 |
% | 80        |-4.813    3.459     -0.004568  |-0.01887   3.459     -1.165 |
%  ------------------------------------------------------------------------

clc; clear ;close all
% 载入文件夹
pathName = ‘.\‘;
fileType = ‘*.bmp‘;
files    = dir([pathName fileType]);
len      = length(files);

for pic = 5%1:1:len
    srcName = files(pic).name;
    srcImg  = imread(srcName);
    srcHSV  = rgb2hsv(srcImg);
    srcH    = srcHSV(:,:,1);
    srcS    = srcHSV(:,:,2);
    srcV    = srcHSV(:,:,3);
    meanS   = mean(srcS(:));
    varS    = std2(srcS);
    %图像整体进行色彩增强处理
    if (meanS >= 0.5)
        p1 = 0;p2 = 0;p3 = 0;
    else if (meanS >= 0.35 && meanS < 0.5)
            p1 = -0.1661;p2 = 0.2639;p3 = -0.003626;
        else if (meanS >=0.2 && meanS <0.35)
                p1 = -0.4025;p2 = 0.6238;p3 = -0.0005937;
            else
                p1 = 1.332;p2 = 1.473;p3 = -0.01155;
            end
        end
    end
    dstS = srcS + p1*srcS.*srcS + p2*srcS + p3 ;
    dstHSV = srcHSV;
    dstHSV(:,:,2) = dstS;
    dstImg = hsv2rgb(dstHSV);
    figure;imshow(srcImg);
    figure;imshow(dstImg);
    %指定R,G,B通道进行色彩增强处理,红色范围([225-255]),绿色范围(75-[105-135]-165),蓝色范围([-15-15])
    p11 = -0.4025;p21 = 0.6238;p31 = -0.0005937;%周边杂色调整系数,40
    p12 = 1.332;  p22 = 1.473; p32 = -0.01155;  %纯色区域调整系数,60
    compHue = srcH;
    GcompS  = dstS;
    RcompS  = dstS;
    BcompS  = dstS;
    channel = ‘B‘;
    switch channel
        case ‘G‘
            I1 = find(compHue > 0.2083 & compHue <0.2917);
            GcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;
            I2 = find(compHue >= 0.2917 & compHue <= 0.3750);
            GcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;
            I3 = find(compHue > 0.3750 & compHue <0.4583);
            GcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;
            compHSV = dstHSV;
            compHSV(:,:,2) = GcompS;
            dstImgG = hsv2rgb(compHSV);
            figure;imshow(dstImgG);
        case ‘R‘
            I1 = find(compHue > 0.875 & compHue <0.9583);
            RcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;
            I2 = find(compHue >= 0.9583 | compHue <= 0.0417);
            RcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;
            I3 = find(compHue > 0.0417 & compHue <0.125);
            RcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;
            compHSV = dstHSV;
            compHSV(:,:,2) = RcompS;
            dstImgR = hsv2rgb(compHSV);
            figure;imshow(dstImgR);
        case ‘B‘
            I1 = find(compHue > 0.5417 & compHue <0.625);
            BcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;
            I2 = find(compHue >= 0.625 & compHue <= 0.7083);
            BcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;
            I3 = find(compHue > 0.7083 & compHue <0.7917);
            BcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;
            compHSV = dstHSV;
            compHSV(:,:,2) = BcompS;
            dstImgB = hsv2rgb(compHSV);
            figure;imshow(dstImgB);
    end
    %进行R,G,B通道之间的互换
    convH = zeros(size(srcH,1),size(srcH,2)); %convert
    deltaHue = 240;
    switch deltaHue
        case 120
            disp(‘R -> G‘)
            convH = srcH + 1/3;
            convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;
        case 240
            disp(‘R -> B‘)
            convH = srcH + 2/3;
            convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;
    end
    convHSV = dstHSV;
    convHSV(:,:,1) = convH;
    convImg = hsv2rgb(convHSV);
    figure;imshow(convImg)
    pause();
end
 
   添加OpenCV代码段:
 


[cpp] view plain copy print?


Mat srcHSV,sat,satAdj,dstMerge,dst;     //sat - saturation饱和度分量  
Mat imageAwb = imread("m_ImageAwb.bmp");  
vector<Mat> channels,channels1;  
double p1,p2,p3;  
  
cvtColor(imageAwb,srcHSV,CV_BGR2HSV);  
split(srcHSV,channels);  
split(srcHSV,channels1);  
sat = channels.at(1);  
Scalar m = mean(sat);  
  
if (m(0) <= 51.5)                         
{p1 = -0.002714 , p2 = 0.9498, p3 = -0.5073;  AfxMessageBox("High Color Enhancement!"); }//高  
else if (m(0) > 38.5 && m(0) <= 89.5)    
{p1 = -0.001578  , p2 = 0.6238, p3 = -0.1514;AfxMessageBox("Middle Color Enhancement!"); }//中  
else if (m(0) > 89.5 && m(0) <=127.5)    
{p1 = -0.0006512, p2 = 0.2639, p3 = -0.9246;AfxMessageBox("Low Color Enhancement!");}//低  
else                                     
{p1 = 0,p2 = 0,p3 =0;AfxMessageBox("No Color Enhancement!");}  
  
satAdj = sat;  
for (int i = 0 ; i < sat.rows;i ++)  
{  
    for (int j = 0;j < sat.cols;j ++)  
    {  
        uchar val = sat.at<uchar>(i,j);  
        satAdj.at<uchar>(i,j) = (val + p1 * val * val + p2 * val + p3) ;  
    }  
}  
  
channels1.at(1) = satAdj;  
merge(channels1,dstMerge);  
cvtColor(dstMerge,dst,CV_HSV2BGR);  
imwrite("m_ImageCE.bmp",dst);  

 Mat srcHSV,sat,satAdj,dstMerge,dst;     //sat - saturation饱和度分量
 Mat imageAwb = imread("m_ImageAwb.bmp");
 vector<Mat> channels,channels1;
 double p1,p2,p3;

 cvtColor(imageAwb,srcHSV,CV_BGR2HSV);
 split(srcHSV,channels);
 split(srcHSV,channels1);
 sat = channels.at(1);
 Scalar m = mean(sat);

 if (m(0) <= 51.5)                    
 {p1 = -0.002714 , p2 = 0.9498, p3 = -0.5073;  AfxMessageBox("High Color Enhancement!"); }//高
 else if (m(0) > 38.5 && m(0) <= 89.5)  
 {p1 = -0.001578  , p2 = 0.6238, p3 = -0.1514;AfxMessageBox("Middle Color Enhancement!"); }//中
 else if (m(0) > 89.5 && m(0) <=127.5)  
 {p1 = -0.0006512, p2 = 0.2639, p3 = -0.9246;AfxMessageBox("Low Color Enhancement!");}//低
 else                                   
 {p1 = 0,p2 = 0,p3 =0;AfxMessageBox("No Color Enhancement!");}

 satAdj = sat;
 for (int i = 0 ; i < sat.rows;i ++)
 {
  for (int j = 0;j < sat.cols;j ++)
  {
   uchar val = sat.at<uchar>(i,j);
   satAdj.at<uchar>(i,j) = (val + p1 * val * val + p2 * val + p3) ;
  }
 }

 channels1.at(1) = satAdj;
 merge(channels1,dstMerge);
 cvtColor(dstMerge,dst,CV_HSV2BGR);
 imwrite("m_ImageCE.bmp",dst);    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注常用软件Photoshop频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程