PS里的亮度/对比度/饱和度/色阶算法-OpenGL实现

本文介绍了如何使用OpenGL进行图像处理,包括亮度、对比度、饱和度和色阶的调整。通过调整像素RGB值,实现了图片亮度的增减;通过对比度调整,使图片明暗对比更鲜明;通过HSV转换调整饱和度,增强或减弱图像色彩;最后,通过色阶调整,改变图像的明暗分布。这些方法为图像处理提供了基本的技术支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.亮度

  • PS里的亮度调整,主要是控制图片整体的亮度,可以弥补曝光过度和曝光补足需要补光的问题。
    在这里插入图片描述
  • 对RGB图像来说,亮度算法有很多种,最简单的一种就是直接整体提升或降低像素的RGB值。(RGB值为0到1,0纯黑,1纯白)
  • 公式如下:
    • 新RGB值 = 旧RGB值 + 亮度值
    • 亮度值在-1到1之间
    • 新RGB值需要控制范围0到1
使用OpenGL实现:

顶点着色器:

attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 texcoordOut;

void main()
{
    texcoordOut = a_texCoord;
    gl_Position = vec4(a_position, 0.0, 1.0);
}

片段着色器:
u_texture为原图,brightness为调整亮度值,变化范围-1到1

precision highp float;

uniform sampler2D u_texture;
varying vec2 texcoordOut;

uniform float brightness;

void main()
{
    vec4 srcColor = texture2D(u_texture, texcoordOut);
    gl_FragColor = vec4(clamp(srcColor.rgb + brightness, 0.0, 1.0), srcColor.a);
}
效果:

请添加图片描述

2.对比度

  • PS里的对比度调整,可以增大图片明暗区别,两处更亮,暗处更暗,使得明暗更分明在这里插入图片描述

  • 对RGB图像来说,对比度算法依然有很多种,在不知道图像平均亮度的情况下,可以取0.5作为图像的平均亮度。超出0.5的像素做类似提亮的操作,低于0.5的像素做类似压暗的操作。(RGB值为0到1,0纯黑,1纯白)

  • 公式如下:

    • 新RGB值 = 旧RGB值 + (旧RGB值 - 0.5)× 对比度值
    • 对比度值在0到1之间
    • 新RGB值需要控制范围0到1
使用OpenGL实现:

顶点着色器:

attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 texcoordOut;

void main()
{
    texcoordOut = a_texCoord;
    gl_Position = vec4(a_position, 0.0, 1.0);
}

片段着色器:
u_texture为原图,contrast为调整对比度值,变化范围0到1

precision highp float;

uniform sampler2D u_texture;
varying vec2 texcoordOut;

uniform float contrast;

void main()
{
    vec4 srcColor = texture2D(u_texture, texcoordOut);
    vec3 contrastColor = srcColor.rgb + (srcColor.rgb - vec3(0.5)) * contrast;
    gl_FragColor = vec4(clamp(contrastColor, 0.0, 1.0), srcColor.a);
}
效果:

请添加图片描述

3.饱和度

  • PS里的饱和度调整,可以使得颜色更饱满,更鲜艳。降低饱和度时,图片会越接近灰色(相当于失去了所有的色彩)
    在这里插入图片描述

  • 饱和度调整算法,需要先将RGB颜色转为HSV颜色,然后调整其S部分,最后再传唤回RGB颜色。从而达到线性调整饱和度的目的。(RGB值为0到1,0纯黑,1纯白)

  • PS饱和度调整算法主要是利用HSL颜色空间进行饱和度S的上下限控制,对RGB空间进行补丁式调整。调整过程是在RGB空间进行,其原理简单的说就是判断每个像素点R/G/B值是否大于或小于平均值,大于加上调整值,小于则减去调整值,如何计算各个像素点的调整系数是关键。本算法主体思想就是利用HSL来计算各点的调整系数。

  • 公式如下:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

使用OpenGL实现:

顶点着色器:

attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 texcoordOut;

void main()
{
    texcoordOut = a_texCoord;
    gl_Position = vec4(a_position, 0.0, 1.0);
}

片段着色器:
u_texture为原图,saturation为调整饱和度值,变化范围-1到1

precision highp float;

uniform sampler2D u_texture;
varying vec2 texcoordOut;

uniform float saturation;

void main()
{
    vec4 srcColor = texture2D(u_texture, texcoordOut);
    
    float rgbMax = max(max(srcColor.r, srcColor.g), srcColor.b);
    float rgbMin = min(min(srcColor.r, srcColor.g), srcColor.b);
    
    float delta = rgbMax - rgbMin;
    
    float value = rgbMax + rgbMin;
    
    // HSL
    float L = value / 2.0;
    float S;
    if (L < 0.5) {
        S = delta / value;
    } else {
        S = delta / (2.0 - value);
    }
    
    float alpha;
    vec3 resultColor;
    if (saturation < 0.0) {
        alpha = saturation;
        resultColor = vec3(L) + (srcColor.rgb - vec3(L)) * (1.0 + alpha);
    } else {
        if (saturation + S >= 1.0) {
            alpha = S;
        } else {
            alpha = 1.0 - saturation;
        }
        alpha = 1.0 / alpha - 1.0;
        resultColor = srcColor.rgb + (srcColor.rgb - vec3(L)) * alpha;
    }
    
    gl_FragColor = vec4(clamp(resultColor, 0.0, 1.0), srcColor.a);
}
效果:

请添加图片描述

4.色阶

  • 色阶是什么:色阶就是用直方图描述出的整张图片的明暗信息。
  • 从左至右是从暗到亮的像素分布,黑色三角代表最暗地方(纯黑),白色三角代表最亮地方(纯白)。灰色三角代表中间调。

在这里插入图片描述

  • 每一个色阶定义有两组值:

    • 一组是输入色阶值,包含黑灰白三个值, 上图中:黑点值为0,灰点为1.0,白点为255
    • 另一组是输入色阶值,包含黑白两个值,上图中:输出色阶黑为0,白为255
  • 色阶调整的实现是:

    • 当输入值<黑点值时,全部变为输出色阶的黑值。
    • 当输入值>白点时,全部变为输出色阶的白值。
    • 当输入值介于黑值与白值之间时,则结合灰度系数,按比例重新计算,变为一个新的值。
使用OpenGL实现:

顶点着色器:

attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 texcoordOut;

void main()
{
    texcoordOut = a_texCoord;
    gl_Position = vec4(a_position, 0.0, 1.0);
}

片段着色器:
u_texture为原图,highLight为白点值,变化范围0到1,shadow为黑点值,变化范围0到1,midtone为灰点值,变化范围0到1。 需要注意必须满足:shadow < midtone< highLight

precision highp float;

uniform sampler2D u_texture;
varying vec2 texcoordOut;

uniform float highLight;
uniform float shadow;
uniform float midtone;

void main()
{
    vec4 srcColor = texture2D(u_texture, texcoordOut);
    
    float diff = highLight - shadow;
    vec3 rgbDiff = max(srcColor.rgb - shadow, 0.0);
    
    gl_FragColor = vec4(clamp(pow(rgbDiff / diff, vec3(1.0 / midtone)), 0.0, 1.0), srcColor.a);
}
效果:

效果为黑点值0.1,白点值0.9,只移动灰点值的效果:
请添加图片描述

### 回答1: 这是一个出现在编译器或者命令行窗口的错误信息,提示程序创建一个进程(create process)出现了问题(process begin),可能是由于输入的命令或者参数出现了错误。具体问题需要根据错误信息及其上下文进行分析和排查。 ### 回答2: 我很抱歉,但是您给出的信息不够详细,我不能够理解您想询问的是什么问题。在编程语言中,"process_begin: createprocess(n"是一种错误提示,通常出现在编译过程中,它意味着正在创建一个进程,但是创建过程出现了错误。通常,此错误可能是由于以下原因引起的: 1)命令行参数格式不正确。您可能未正确指定程序的路径或所需的参数。 2)进程正在运行,但由于某种原因导致了错误,比如权限问题,输入输出问题或者程序错误。 3)您正在尝试运行不存在的程序。 为了解决这个问题,您可以尝试以下几种方法。 首先,您需要查看编译器或者开发环境的错误日志,以获取更详细的错误信息,这将有助于您找到问题的根源。 其次,您可以检查程序的路径,确保程序文件存在,并检查所需的参数是否正确。 第三,您可以查看您的系统日志,以了解是什么导致了错误,比如权限问题或者输入输出问题。 最后,您可以尝试重新编译程序,并确保在进行编译时使用了正确的选项,以减少错误的可能性。 总之,由于"process_begin: createprocess(n"的原因可能有很多,如果您希望得到更详细的帮助,请提供更多的信息,以便我能够帮助您找到问题的根源,并提供解决方案。 ### 回答3: Process_begin: createprocess(n. 这个错误常常出现在编程的过程中,通常与程序的编译有关,也可能与程序运行过程中的某些因素有关。这个错误会提示你编译或运行程序的过程中出现了错误,让程序无法执行完成。为了解决这个问题,我们需要了解一些可能导致该问题出现的原因,以便我们能够采取相应的措施,解决该问题。 可能导致该问题出现的原因: 1. 编辑器或编译器中路径未正确配置:如果没有正确地设置路径,就会出现该问题。 2. 电脑中的病毒或恶意软件:如果病毒或恶意软件感染了您的计算机系统,也可能导致该问题的出现。 3. 程序编写错误:如果程序编写出现了错误,也可能导致该问题的出现。 4. 输入输出问题:如果程序的输入输出存在问题,也可能导致该问题的出现。 如何解决该问题: 1. 首先,我们需要检查路径是否正确,在编译器或编辑器中进行设置,确保路径正确无误。 2. 如果计算机系统感染了病毒或其他恶意软件,请运行防病毒软件或修复的软件,确保计算机系统中没有病毒。 3. 检查程序代码,查看是否存在编写错误并进行修改。 4. 检查程序的输入输出,确保没有问题。 结论: Process_begin: createprocess(n)错误通常与程序编译或运行有关,可能由于路径设置不正确,计算机系统感染病毒或其他恶意软件,程序编写错误,或者输入输出的问题导致。如果遇到该问题,我们需要检查并解决这些因素。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值