您的位置:首页 > 运维架构

Photoshop图像处理算法—饱和度调整

2015-08-27 21:26 387 查看
前言:之前在公司做项目的用到photoshop颜色空间的一些相关方法,在此总结一下。下面原理部分是从我的总结文档里截取来的。需要复制的童鞋自己手写一下~











2、程序部分

1)Matlab实验程序。
<span style="font-size:18px;">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);</span><span style="font-weight: bold; font-size: 18px;">
</span>


2)C程序,此处只贴上关键处理部分,已经把图像变成了数组来处理

<span style="font-size:18px;">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<double>(rgbMax - rgbMin) / 255;
		dValue  = static_cast<double>(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;
	}

}</span>


3、实验结果,与photoshop处理结果一致



图1
原图



图2
参数为50的结果



图2
参数为-50的结果
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: