ISP模塊之色彩增強算法--HSV空間Saturation通道調整 .


    色彩增強不同於彩色圖像增強,圖像增強的一般處理方式為直方圖均衡化等,目的是為了增強圖像局部以及整體對比度。而色彩增強的目的是為了使的原有的不飽和的色彩信息變得飽和、豐富起來。對應於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進行擬合,得到曲線參數。

 

  1. % Color Enhancement  
  2. clc,clear,close all  
  3. src1 = imread('src.bmp');  
  4. src2 = imread('src_40.bmp');  
  5.   
  6. src1_hsv = rgb2hsv(src1);  
  7. src2_hsv = rgb2hsv(src2);  
  8.   
  9. h1 = src1_hsv(:,:,1);  
  10. s1 = src1_hsv(:,:,2);  
  11. v1 = src1_hsv(:,:,3);  
  12.   
  13. h2 = src2_hsv(:,:,1);  
  14. s2 = src2_hsv(:,:,2);  
  15. v2 = src2_hsv(:,:,3);  
  16. %   
  17. meanS1 = mean(s1(:));  
  18. varS1  = std2(s1);   
  19. %   
  20. meanS2 = mean(s2(:));  
  21. varS2  = std2(s2);   
  22. %   
  23. deltaS = s2 - s1;  
  24. deltaV = v2 - v1;  
  25.   
  26. %% test1 : 觀測“原飽和度-飽和度調整增量”的關系 saturation and delta saturation  
  27. figure;  
  28. oriS = zeros(101,2);  
  29. s3 = s1;  
  30. j = 1;  
  31. for i = 0: 0.01 : 1  
  32.     oriS(j,1) = i + 0.01;  
  33.     oriS(j,2) =  mean(deltaS(find(s1 > i & s1< i + 0.01)));  
  34.     j = j + 1;  
  35. end  
  36. X  = oriS(:,1);  
  37. Y  = oriS(:,2);  
  38. XX = oriS(:,1) * 255;  
  39. YY = oriS(:,2) * 255;  
  40. 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)

 

   第二部分,對輸入圖像進行高、中、低三級自適應增強處理

 

  1. %% Color Enhancement Module -- Authored by HuangDao,08/17/2015  
  2. % functions: input a image of type BMP or PNG, the program will decide to  
  3. % do the Color Enhancement choice for you.There are four types of Enhanced  
  4. % intensity - 20,40,60,80.The larger number stands for stronger  
  5. % enhancement.  
  6. % And we can also choose the simple color channel(eg.R,G,B) to do the  
  7. % enhancement.There are also four different types of enhanced intensity.  
  8. %  
  9. % parameters table  
  10. %  ------------------------------------------------------------------------  
  11. % | Enhanced  |     MATLAB params             |      OpenCV params         |  
  12. % | intensity |p1        p2        p3         | p1        p2        p3     |  
  13. % | 20        |-0.1661   0.2639    -0.003626  |-0.0006512 0.2639    -0.9246|  
  14. % | 40        |-0.4025   0.6238    -0.0005937 |0.001578   0.6238    -0.1514|  
  15. % | 60        |1.332     1.473     -0.01155   |-0.005222  1.473     -2.946 |  
  16. % | 80        |-4.813    3.459     -0.004568  |-0.01887   3.459     -1.165 |  
  17. %  ------------------------------------------------------------------------  
  18.   
  19. clc; clear ;close all  
  20. % 載入文件夾  
  21. pathName = '.\';  
  22. fileType = '*.bmp';  
  23. files    = dir([pathName fileType]);  
  24. len      = length(files);  
  25.   
  26. for pic = 5%1:1:len  
  27.     srcName = files(pic).name;  
  28.     srcImg  = imread(srcName);  
  29.     srcHSV  = rgb2hsv(srcImg);  
  30.     srcH    = srcHSV(:,:,1);  
  31.     srcS    = srcHSV(:,:,2);  
  32.     srcV    = srcHSV(:,:,3);  
  33.     meanS   = mean(srcS(:));  
  34.     varS    = std2(srcS);  
  35.     %圖像整體進行色彩增強處理  
  36.     if (meanS >= 0.5)  
  37.         p1 = 0;p2 = 0;p3 = 0;  
  38.     else if (meanS >= 0.35 && meanS 0.5)  
  39.             p1 = -0.1661;p2 = 0.2639;p3 = -0.003626;  
  40.         else if (meanS >=0.2 && meanS <0.35)  
  41.                 p1 = -0.4025;p2 = 0.6238;p3 = -0.0005937;  
  42.             else  
  43.                 p1 = 1.332;p2 = 1.473;p3 = -0.01155;  
  44.             end  
  45.         end  
  46.     end  
  47.     dstS = srcS + p1*srcS.*srcS + p2*srcS + p3 ;  
  48.     dstHSV = srcHSV;  
  49.     dstHSV(:,:,2) = dstS;  
  50.     dstImg = hsv2rgb(dstHSV);  
  51.     figure;imshow(srcImg);  
  52.     figure;imshow(dstImg);  
  53.     %指定R,G,B通道進行色彩增強處理,紅色范圍([225-255]),綠色范圍(75-[105-135]-165),藍色范圍([-15-15])  
  54.     p11 = -0.4025;p21 = 0.6238;p31 = -0.0005937;%周邊雜色調整系數,40  
  55.     p12 = 1.332;  p22 = 1.473; p32 = -0.01155;  %純色區域調整系數,60  
  56.     compHue = srcH;  
  57.     GcompS  = dstS;  
  58.     RcompS  = dstS;  
  59.     BcompS  = dstS;  
  60.     channel = 'B';  
  61.     switch channel  
  62.         case 'G'  
  63.             I1 = find(compHue > 0.2083 & compHue <0.2917);  
  64.             GcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;  
  65.             I2 = find(compHue >= 0.2917 & compHue <= 0.3750);  
  66.             GcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;  
  67.             I3 = find(compHue > 0.3750 & compHue <0.4583);  
  68.             GcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;  
  69.             compHSV = dstHSV;  
  70.             compHSV(:,:,2) = GcompS;  
  71.             dstImgG = hsv2rgb(compHSV);  
  72.             figure;imshow(dstImgG);  
  73.         case 'R'  
  74.             I1 = find(compHue > 0.875 & compHue <0.9583);  
  75.             RcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;  
  76.             I2 = find(compHue >= 0.9583 | compHue <= 0.0417);  
  77.             RcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;  
  78.             I3 = find(compHue > 0.0417 & compHue <0.125);  
  79.             RcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;  
  80.             compHSV = dstHSV;  
  81.             compHSV(:,:,2) = RcompS;  
  82.             dstImgR = hsv2rgb(compHSV);  
  83.             figure;imshow(dstImgR);  
  84.         case 'B'  
  85.             I1 = find(compHue > 0.5417 & compHue <0.625);  
  86.             BcompS(I1) = dstS(I1) + dstS(I1).*dstS(I1)*p11 + dstS(I1)*p21 + p31;  
  87.             I2 = find(compHue >= 0.625 & compHue <= 0.7083);  
  88.             BcompS(I2) = dstS(I2) + dstS(I2).*dstS(I2)*p12 + dstS(I2)*p22 + p32;  
  89.             I3 = find(compHue > 0.7083 & compHue <0.7917);  
  90.             BcompS(I3) = dstS(I3) + dstS(I3).*dstS(I3)*p11 + dstS(I3)*p21 + p31;  
  91.             compHSV = dstHSV;  
  92.             compHSV(:,:,2) = BcompS;  
  93.             dstImgB = hsv2rgb(compHSV);  
  94.             figure;imshow(dstImgB);  
  95.     end  
  96.     %進行R,G,B通道之間的互換  
  97.     convH = zeros(size(srcH,1),size(srcH,2)); %convert  
  98.     deltaHue = 240;  
  99.     switch deltaHue  
  100.         case 120  
  101.             disp('R -> G')  
  102.             convH = srcH + 1/3;  
  103.             convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;  
  104.         case 240  
  105.             disp('R -> B')  
  106.             convH = srcH + 2/3;  
  107.             convH(find(convH >= 1)) = convH(find(convH >= 1)) - 1;  
  108.     end  
  109.     convHSV = dstHSV;  
  110.     convHSV(:,:,1) = convH;  
  111.     convImg = hsv2rgb(convHSV);  
  112.     figure;imshow(convImg)  
  113.     pause();  
  114. 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代碼段:

 

  1. Mat srcHSV,sat,satAdj,dstMerge,dst;     //sat - saturation飽和度分量  
  2. Mat imageAwb = imread("m_ImageAwb.bmp");  
  3. vector<Mat> channels,channels1;  
  4. double p1,p2,p3;  
  5.   
  6. cvtColor(imageAwb,srcHSV,CV_BGR2HSV);  
  7. split(srcHSV,channels);  
  8. split(srcHSV,channels1);  
  9. sat = channels.at(1);  
  10. Scalar m = mean(sat);  
  11.   
  12. if (m(0) <= 51.5)                         
  13. {p1 = -0.002714 , p2 = 0.9498, p3 = -0.5073;  AfxMessageBox("High Color Enhancement!"); }//高  
  14. else if (m(0) > 38.5 && m(0) <= 89.5)    
  15. {p1 = -0.001578  , p2 = 0.6238, p3 = -0.1514;AfxMessageBox("Middle Color Enhancement!"); }//中  
  16. else if (m(0) > 89.5 && m(0) <=127.5)    
  17. {p1 = -0.0006512, p2 = 0.2639, p3 = -0.9246;AfxMessageBox("Low Color Enhancement!");}//低  
  18. else                                     
  19. {p1 = 0,p2 = 0,p3 =0;AfxMessageBox("No Color Enhancement!");}  
  20.   
  21. satAdj = sat;  
  22. for (int i = 0 ; i < sat.rows;i ++)  
  23. {  
  24.     for (int j = 0;j < sat.cols;j ++)  
  25.     {  
  26.         uchar val = sat.at<uchar>(i,j);  
  27.         satAdj.at<uchar>(i,j) = (val + p1 * val * val + p2 * val + p3) ;  
  28.     }  
  29. }  
  30.   
  31. channels1.at(1) = satAdj;  
  32. merge(channels1,dstMerge);  
  33. cvtColor(dstMerge,dst,CV_HSV2BGR);  
  34. 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);

 

   最后給出算法效果圖:

Group1.原圖->增強后

 

Group2.原圖->R通道增強->顏色通道改變R2B

Group3.原圖->增強后->顏色通道改變R2B

完!下篇講Local Tone Mapping。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM