PhotoShop的饱和度调节公式:
①计算每个像素点三基色最小值和最大值
②delta为两值之差 / 255,如果两值之差为0则不做操作
value为两值之和 / 255
③有RGB图像空间转化成HSL(H色调,S饱和度,L亮度)
L = value / 2
如果L < 0.5 则 S = delta / value;
否则 S = delta / (2 - value);
④Increment / 100 为饱和度
正值为提升饱和度,负值为降低饱和度。
根据不同公式得到新的rgb值。
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
#define max2(a, b) ( (a) > (b) ) ? (a) : (b)
#define max3(a,b,c) ( ( (a) > (b) ) ? max2( a, c) : max2( b, c ) )
#define min2(a, b) ( (a) < (b) ) ? (a) : (b)
#define min3(a,b,c) ( ( (a) < (b) ) ? min2( a, c ) : min2( b, c ) )
const int max_Increment = 200;
int Increment_value;
Mat image;
Mat src;
void on_Trackbar(int , void*)
{
float Increment= (Increment_value - 100)* 1.0/max_Increment;
image = src.clone();
for(int i = 0; i < image.cols; ++i)
{
for(int j = 0; j < image.rows; ++j)
{
uchar b = image.at<Vec3b>(j, i).val[0];
uchar g = image.at<Vec3b>(j, i).val[1];
uchar r = image.at<Vec3b>(j, i).val[2];
float max = max3(r,g,b);
float min = min3(r,g,b);
float delta, value;
uchar R_new, G_new, B_new;
float L, S, alpha;
delta = (max - min) / 255;
if(delta == 0)
continue;
value = (max + min) / 255;
L = value / 2;
if(L < 0.5)
S = delta / value;
else
S = delta / (2 - value);
if(Increment >= 0)
{
if((Increment + S) >= 1)
alpha = S;
else
alpha = 1 - Increment;
alpha = 1 / alpha - 1;
R_new = r + (r - L * 255) * alpha;
G_new = g + (g - L * 255) * alpha;
B_new = b + (b - L * 255) * alpha;
}
else
{
alpha = Increment;
R_new = L * 255 + (r - L * 255) * (1+alpha);
G_new = L * 255 + (g - L * 255) * (1+alpha);
B_new = L * 255 + (b - L * 255) * (1+alpha);
}
image.at<Vec3b>(j, i).val[0] = B_new;
image.at<Vec3b>(j, i).val[1] = G_new;
image.at<Vec3b>(j, i).val[2] = R_new;
}
}
imshow("image",image);
}
void main()
{
image = imread("lena.png");
src = image.clone();
Increment_value = 100;
namedWindow("image", 1);
createTrackbar("饱和度", "image", &Increment_value, 200, on_Trackbar);
on_Trackbar(Increment_value, 0);
waitKey();
image.release();
src.release();
}