图像处理相关算法之饱和度调整
程序员文章站
2022-07-14 16:52:12
...
调整饱和度的方法,代码如下:
void AdjustSatuation(cv::Mat &image, float adjust) {
int width = image.cols, height = image.rows;
for (int i = 0; i < height; ++i) {
auto data = image.ptr<cv::Vec3b>(i);
for (int j = 0; j < width; ++j) {
float lum = data[j][0] * 0.299f + data[j][1] * 0.587f + data[j][2] * 0.114f;
float maskB = std::max(0.0f, std::min(data[j][0] - lum, 255.0f)) / 255.0f;
float maskG = std::max(0.0f, std::min(data[j][1] - lum, 255.0f)) / 255.0f;
float maskR = std::max(0.0f, std::min(data[j][2] - lum, 255.0f)) / 255.0f;
float lumMask = (1.0f - (maskB * 0.299f + maskG * 0.587f + maskR * 0.114f)) * adjust;
data[j][0] = cv::saturate_cast<uchar>(data[j][0] * (1.0f + lumMask) - lum * lumMask);
data[j][1] = cv::saturate_cast<uchar>(data[j][1] * (1.0f + lumMask) - lum * lumMask);
data[j][2] = cv::saturate_cast<uchar>(data[j][2] * (1.0f + lumMask) - lum * lumMask);
}
}
}
调整前后对比:
其中adjust取值范围为[-1,1]
另一种饱和度调整算法:
void AdjustSatuation(const cv::Mat &src, cv::Mat &dst, int percent) {
dst.create(src.size(), src.type());
int width = src.cols, height = src.rows;
int channels = src.channels();
if (channels != 3 || src.type() != CV_8UC3) {
return;
}
float ratio1 = 1 / 255.0f;
float adjust = std::max(std::min(percent, 100), -100) / 100.0f;
for (int i = 0; i < height; ++i) {
auto srcData = src.ptr<uchar>(i);
auto dstData = dst.ptr<uchar>(i);
for (int j = 0; j < width; ++j) {
int j3 = j * 3;
int r = srcData[j3 + 2];
int g = srcData[j3 + 1];
int b = srcData[j3];
int maxV = std::max(r, std::max(g, b));
int minV = std::min(r, std::min(g, b));
float delta = (maxV - minV) * ratio1;
if (delta < 1e-3f) {
dstData[j3] = b;
dstData[j3 + 1] = g;
dstData[j3 + 2] = r;
continue;
}
float value = (maxV + minV) * ratio1;
float L = value / 2.0f;
float S = delta / value;
if (L >= 0.5f) {
S = delta / (2.0f - value);
}
if (percent >= 0) {
float alpha = 1.0f - adjust;
if (adjust + S >= 1) {
alpha = S;
}
alpha = 1.0f / alpha - 1.0f;
dstData[j3] = cv::saturate_cast<uchar>(b + (b - L * 255.0f) * alpha);
dstData[j3 + 1] = cv::saturate_cast<uchar>(g + (g - L * 255.0f) * alpha);
dstData[j3 + 2] = cv::saturate_cast<uchar>(r + (r - L * 255.0f) * alpha);
}
else {
float alpha = 1.0f + adjust;
dstData[j3] = cv::saturate_cast<uchar>(L * 255.0f + (b - L * 255.0f) * alpha);
dstData[j3 + 1] = cv::saturate_cast<uchar>(L * 255.0f + (g - L * 255.0f) * alpha);
dstData[j3 + 2] = cv::saturate_cast<uchar>(L * 255.0f + (r - L * 255.0f) * alpha);
}
}
}
}
调整后的图像结果为:
上一篇: 要嫁就嫁程序员
下一篇: 推荐一个手机应用开发的好的博客网站