前言:之前在公司做项目的用到photoshop颜色空间的一些相关方法,在此总结一下。下面原理部分是从我的总结文档里截取来的。需要复制的童鞋自己手写一下~
2、程序部分
1)Matlab实验程序。
clc;clear all;close all;
Image=imread('Fotor_LomoOrg.bmp');
Image=double(Image);
R=Image(:,:,1);
G=Image(:,:,2);
B=Image(:,:,3);
[row, col] = size(R);
R_new=R;
G_new=G;
B_new=B;
%%%% Increment, 饱和度调整增量(-100,100)photoshop的范围
Increment=-50;
%换算成调整比率
Increment=Increment/100;
%利用HSL模式求得颜色的S和L
for i=1:row
for j=1:col
rgbMax=max(R(i,j),max(G(i,j),B(i,j)));
rgbMin=min(R(i,j),min(G(i,j),B(i,j)));
Delta=(rgbMax-rgbMin)/255;
if(Delta==0) %如果delta=0,则饱和度S=0,所以不能调整饱和度
continue;
end
value = (rgbMax + rgbMin)/255;
L=value/2; %Lightness
if(L<0.5) %根据明度L计算饱和度S
S=Delta/value;
else
S =Delta/(2 - value);
end
%具体的饱和度调整,Increment为饱和度增减量
if (Increment>=0)
if((Increment+S)>=1)
alpha=S;
else
alpha=1-Increment;
end
alpha=1/alpha-1;
R_new(i,j) = R(i,j) + (R(i,j) - L * 255) * alpha;
G_new(i,j) = G(i,j) + (G(i,j) - L * 255) * alpha;
B_new(i,j) = B(i,j) + (B(i,j) - L * 255) * alpha;
else
alpha=Increment;
R_new(i,j) = L*255 + (R(i,j) - L * 255) * (1+alpha);
G_new(i,j) = L*255 + (G(i,j) - L * 255) * (1+alpha);
B_new(i,j) = L*255 + (B(i,j) - L * 255) * (1+alpha);
end
end
end
Image_new(:,:,1)=R_new;
Image_new(:,:,2)=G_new;
Image_new(:,:,3)=B_new;
imshow(Image/255);
figure, imshow(Image_new/255);
void SaturationAdjustRGB(unsigned char *pSrc, unsigned char *pDest, int nWidth, int nHeight,int nParameter)
{
//局部变量声明
int i = 0;
int t = 0;
int nLength = nHeight * nWidth;
//参数处理
double dPercent= static_cast< double >(nParameter) / 100;
//RGB颜色通道声明
unsigned char *imgR = new unsigned char[nLength];
unsigned char *imgG = new unsigned char[nLength];
unsigned char *imgB = new unsigned char[nLength];
//局部变量声明
unsigned char rgbMax;
unsigned char rgbMin;
double dDelta;
double dValue;
double dL;
double dS;
double dAlpha;
//分离出RGB通道
for (i = 0; i < nLength; i++)
{
t = 3 * i;
imgB[i] = pSrc[t];
imgG[i] = pSrc[t + 1];
imgR[i] = pSrc[t + 2];
}
for (int i = 0; i < nLength; i++)
{
rgbMax = max(max(imgR[i] , imgG[i]) , imgB[i]);
rgbMin = min(min(imgR[i] , imgG[i]) , imgB[i]);
dDelta = static_cast(rgbMax - rgbMin) / 255;
dValue = static_cast(rgbMax + rgbMin) / 255;
//如果该像素点是灰色 不处理
if(0 == dDelta)
{
continue;
}
//按照公式计算明度L [0,1]
dL = dValue / 2;
//按照公式计算饱和度S [0,1]
if(dL < 0.5)
{
dS = dDelta / dValue;
}
else
{
dS = dDelta / (2 - dValue);
}
//进行饱和度调整
if(dPercent >= 0)
{
if(dPercent + dS >= 1)
{
dAlpha = dS;
}
else
{
dAlpha = 1 - dPercent;
}
dAlpha = 1 / dAlpha - 1;
imgB[i] = imgB[i] + (imgB[i] - dL * 255) * dAlpha;
imgG[i] = imgG[i] + (imgG[i] - dL * 255) * dAlpha;
imgR[i] = imgR[i] + (imgR[i] - dL * 255) * dAlpha;
}
else
{
dAlpha = dPercent;
imgB[i] = dL * 255 + (imgB[i] - dL * 255) * (1 + dAlpha);
imgG[i] = dL * 255 + (imgG[i] - dL * 255) * (1 + dAlpha);
imgR[i] = dL * 255 + (imgR[i] - dL * 255) * (1 + dAlpha);
}
}
//得到结果
for(i = 0; i < nLength; i++)
{
t = 3 * i;
pDest[t] = imgB[i];
pDest[t + 1] = imgG[i];
pDest[t + 2] = imgR[i];
}
//释放内存
if(!imgR)
{
delete []imgR;
imgR = NULL;
}
if(!imgG)
{
delete []imgG;
imgG = NULL;
}
if(!imgB)
{
delete []imgB;
imgB = NULL;
}
}
图1 原图
图2 参数为50的结果
图2 参数为-50的结果