PS 色阶调整之算法公式原理详解及 Python 实现(色阶原理)

article/2025/2/6 7:01:30

本文介绍了 PS 中色阶的实现原理及公式,并用 Python 实现,自测与 PS 的色阶调整效果基本完全一样(使用和 PS 中色阶相同的参数对比效果,包括各极限值,本文只实现了 RGB 整体色阶的处理,对各个通道的处理逻辑公式是一样的,实际使用会用 OpenGL 实现)

如下图是 PS 中色阶调整的操作面板,可以对 R、G、B 单独的通道或 RGB 整体通道做色阶调整。每个通道或整体有五个参数(红色箭头所指的五个滑块,调整时也可以直接输入值):
inputShadows: 输入图像的黑场阈值,作用是将输入图像中低于该阈值的全变成 0
inputHighlit: 输入图像的白场阈值,作用是将输入图像中高于该阈值的全变成 255
midtone: 中间调,范围是 [0.01, 9.99],默认值是 1.0 在中间,[9.99 – 1.0 – 0.01],从中间往左调,即[1.0, 9.99] 加灰降对比度,往右调减灰加对比度(RGB通道)
outputShadows: 输出图像的黑场阈值,输出图像的最低值为该阈值
outputHighlight: 输出图像的白场阈值,输出图像的最高值为该阈值
在这里插入图片描述
色阶调整的处理转换公式如下:
分输入色阶映射、中间调调整、输出色阶映射共三步处理,上一步处理的输出做为下一步的输入(以下公式用 MarkDown Latex 语法编辑)。

输入色阶映射公式:
V o u t = 255 ∗ V i n − i n S h a d o w s i n H i g h l i g h t s − i n S h a d o w s Vout = 255 * \frac{Vin - inShadows}{inHighlights - inShadows} Vout=255inHighlightsinShadowsVininShadows
V o u t = { 0 if  V o u t < 0 255 if  V o u t > 255 Vout = \left\{ \begin{array}{ll} 0 & \textrm{if $Vout<0$}\\ 255 & \textrm{if $Vout>255$}\\ \end{array} \right. Vout={0255if Vout<0if Vout>255

图片名称

中间调调整:
V o u t = 255 ∗ ( V i n 255.0 ) 1 m i d t o n e s Vout = 255 * (\frac{Vin}{255.0})^\frac{1}{midtones} Vout=255(255.0Vin)midtones1

图片名称

输出色阶映射:
V o u t = V i n 255.0 ∗ ( o u t L i g h h i g h t s − o u t S h a d o w s ) + o u t S h a d o w s Vout = \frac{Vin}{255.0} * (outLighhights - outShadows) + outShadows Vout=255.0Vin(outLighhightsoutShadows)+outShadows

V o u t = { 0 if  V o u t < 0 255 if  V o u t > 255 Vout = \left\{ \begin{array}{ll} 0 & \textrm{if $Vout<0$}\\ 255 & \textrm{if $Vout>255$}\\ \end{array} \right. Vout={0255if Vout<0if Vout>255

图片名称
完整 python 代码如下:
# -*- coding: utf-8 -*-
# @Time    : 2021-02-24 16:45
# @Author  : AlanWang4523
# @FileName: ps_levels.pyimport os
import sys
import cv2
import numpy as npclass Levels:"""@Author  : AlanWang4523色阶调整类,根据输入参数调整图片色阶,并输出处理后的图片"""def __init__(self):self.channel = 0self.input_shadows = 0self.input_highlights = 255self.midtones = 1.0self.output_shadows = 0self.output_highlights = 255def adjust_image(self, img):print("Levels Params:")print("          channel:", self.channel)print("    input_shadows:", self.input_shadows)print(" input_highlights:", self.input_highlights)print("         midtones:", self.midtones)print("   output_shadows:", self.output_shadows)print("output_highlights:", self.output_highlights)print("")img = img.astype(np.float)# 输入色阶映射img = 255 * ((img - self.input_shadows) / (self.input_highlights - self.input_shadows))img[img < 0] = 0img[img > 255] = 255# 中间调处理img = 255 * np.power(img / 255.0, 1.0 / self.midtones)# 输出色阶映射img = (img / 255) * (self.output_highlights - self.output_shadows) + self.output_shadowsimg[img < 0] = 0img[img > 255] = 255img = img.astype(np.uint8)return imgdef level_adjust_and_save_img(origin_image):levels.input_shadows = 40levels.input_highlights = 240levels.midtones = 0.60levels.output_shadows = 30levels.output_highlights = 220image = levels.adjust_image(origin_image)cv2.imwrite('py_test_out.png', image)def level_adjust(path):"""色阶调整"""origin_image = cv2.imread(path)levels = Levels()def update_input_shadows(x):if (x < levels.input_highlights):levels.input_shadows = xdef update_input_highlights(x):if (x > levels.input_shadows):levels.input_highlights = xdef update_midtones(x):# 由于 midtones 的调整范围是 [9.99, 0.01],Python 滑杆无法自定义显示小数,因此将滑杆的 [0, 100] 映射到 [9.99, 0.01]midtones = 1.0if (x < 50):midtones = 1 + 9 * ((50.0 - x) / 50.0)elif (x > 50):midtones = 1 - (x - 50) / 50.0levels.midtones = np.clip(midtones, 0.01, 9.99)# levels.midtones = 0.6 # 直接测试某个参数值def update_output_shadows(x):if (x < levels.output_highlights):levels.output_shadows = xdef update_output_highlights(x):if (x > levels.output_shadows):levels.output_highlights = x# 创建图片显示窗口title = "Levels"cv2.namedWindow(title, cv2.WINDOW_NORMAL)   cv2.resizeWindow(title, 800, 600)cv2.moveWindow(title, 0, 0)# 创建色阶操作窗口option_title = "Option"cv2.namedWindow(option_title, cv2.WINDOW_NORMAL)   cv2.resizeWindow(option_title, 400, 200)cv2.moveWindow(option_title, 800, 0)cv2.createTrackbar('    input_shadows', option_title, levels.input_shadows, 255, update_input_shadows)cv2.createTrackbar(' input_highlights', option_title, levels.input_highlights, 255, update_input_highlights)cv2.createTrackbar('         midtones', option_title, 50, 100, update_midtones)cv2.createTrackbar('   output_shadows', option_title, levels.output_shadows, 255, update_output_shadows)cv2.createTrackbar('output_highlights', option_title, levels.output_highlights, 255, update_output_highlights)while True:image = levels.adjust_image(origin_image)cv2.imshow(title, image)if cv2.waitKey(1) == ord('q'):breakcv2.destroyAllWindows()        if __name__ == '__main__':'''Author: AlanWang4523运行环境:Python 3执行:python3 ps_levels.py <图片路径>如:python3 ps_levels.py test.jpg'''if len(sys.argv) == 1:print("参数错误:未传入图片路径!")sys.exit(-1)img_path = sys.argv[1]print("img_path Params:", img_path)level_adjust(img_path)
    def update_midtones(x):# 由于 midtones 的调整范围是 [9.99, 0.01],Python 滑杆无法自定义显示小数,因此将滑杆的 [0, 100] 映射到 [9.99, 0.01]midtones = 1.0if (x < 50):midtones = 1 + 9 * ((50.0 - x) / 50.0)elif (x > 50):midtones = 1 - (x - 50) / 50.0levels.midtones = np.clip(midtones, 0.01, 9.99)# levels.midtones = 0.6 # 直接测试某个参数值

使用和 PS 相同的参数,效果和 PS 上的完全一致,各参数下和 PS 对比效果如下:
(截图上半部部分为用 Python 使用与 PS 相同参数的效果,下半部分为 PS 的效果)
① Python 和 PS 都使用如下参数:
inputShadows: 50
inputHighlit: 52
midtone: 0.50 (根据上面的映射公式,python 实现的 midtones 的滑块在 75 的位置)
outputShadows: 50
outputHighlight: 200
效果如下:
在这里插入图片描述

② Python 和 PS 都使用如下参数:
inputShadows: 0
inputHighlit: 255
midtone: 0.10
outputShadows: 0
outputHighlight: 255
效果如下:
在这里插入图片描述
参考文档:
Adobe 官网的 Levels Adjustment
Algorithm for adjustment of image levels


http://chatgpt.dhexx.cn/article/cOlIMqFQ.shtml

相关文章

第四章 Opencv图像色彩空间与通道

文章目录 1.色彩空间1-1.RGB/BGR色彩空间1-2.GRAY色彩空间1-3.HSV色彩空间 2.通道2-1.拆分通道&#xff1a;split()方法1.拆BGR色彩空间图像的通道2.拆HSV色彩空间图像的通道 2-2.合并通道&#xff1a;merge()方法1.B、G、R 通道的合并2.H、S、V 通道的合并3.B、G、R、A 通道的…

halcon画出灰度直方图_Halcon绘制彩色深度图

此小文主要介绍颜色空间的转换&#xff0c;将深度图转为彩色&#xff0c;借以说明颜色转换与图像通道&#xff0c;下面是效果&#xff1a; 彩色深度图.jpg 深度图的生成 深度图的生成有便捷的算子可用&#xff0c;主要使用了binocular_disparity算子&#xff0c;输入左右两幅图…

【色度学】颜色的显色系统

我的理解&#xff1a; 色相&#xff1a;绝对量&#xff0c;表示颜色。 视明度&#xff1a;人眼视觉对某一刺激量知觉光的数量的多少&#xff0c;是知觉的绝对量。 明度&#xff1a;人眼视觉对某一刺激量直觉出其与周围白点或者最亮区域的相对亮度。 明度 视明度/白场视明度 视彩…

四、色彩空间

一、色彩空间 1、什么是色彩空间&#xff1f; 色彩空间是定义的颜色范围。 2、常见的色彩空间有哪些&#xff1f; ①RGB ②HSV 在OpenCV中&#xff0c;Hue的值为0~180&#xff0c;之所以不是360是因为&#xff0c;8位存不下&#xff0c;故进行归一化操作&#xff0c;使得H…

色彩系统总结

一、基本概念 1、几种色彩模式&#xff1a;RGB、HSB(HSV)、HSL RGB&#xff08;Red 红色、Green 绿色、Blue 蓝色&#xff09; HSB&#xff08;Hue 色相、Saturation 饱和度、Brightness 明度&#xff09; HSB 也称 HSV&#xff08;Hue 色相、Saturation 饱和度、Value 值&…

色阶、灰度色彩模式、灰度等级

色彩三属性图解 色彩的客观三属性与主观三属性 在经典艺用色彩学中&#xff0c;我们只知道一种“色彩三属性”&#xff0c;实际上它只是对人们主观感受色彩的心理描述&#xff0c;建立在人的主观基础之上的对色彩属性的描述&#xff0c;色度学称之为“色彩的主观三属性”。 色彩…

图像的大小计算 位深和色深

图像的大小计算 1、位深和色深 位深&#xff1a;即在某一分辨率下&#xff0c;每一个像素点可以有多少种色彩来描述&#xff0c;单位为“bit”(位)。典型的色深是8-bit、16-bit、24-bit和32-bit。深度数值越高&#xff0c;可以获得更多的色彩。 图像深度是指存储每个像素所用的…

15.色彩空间

目录 一 色彩空间的粗略定义 二 色彩空间的分类 1.利用原色相混的比例表示的色彩空间 2.利用不同的概念表示的色彩空间 &#xff08;1&#xff09;.色相 &#xff08;2&#xff09;饱和度 &#xff08;3&#xff09;明度 &#xff08;4&#xff09;亮度 三 HSV和HSL色…

2.1 色彩空间

色彩发送器 色彩认知&#xff1a;光源是出生点&#xff0c;光源发射出光线&#xff0c;光线通过直射反射折射等路径最终进入人眼。但是人眼接收到光线后&#xff0c;人眼的细胞产生了一系列化学反应。由此把产生的新号传入大脑&#xff0c;最终大脑对颜色产生了认知感知。 光的…

色数(色深”、“灰阶”、“色数”三者的关系)

色数&#xff0c;就是显示器能够显示最大色彩数量。我们在选购显示器时&#xff0c;常常会发现产品资料并未提及色深相关信息&#xff0c;却能看到“1670万色”、“10亿色”之类关于色数的描述&#xff0c;而“10亿色彩”表示该显示器能显示约10亿种不同的颜色。 比如&#xf…

彩色图像色彩空间原理(理论篇—6)

自然界的各种色彩、人类所感知的色彩以及各种图像设备和计算机软件所使用的颜色可通过色彩空间&#xff08;Color Space&#xff09;来描述。 色彩是人脑对不同视觉刺激的反应。人眼视网膜上的色敏细胞会分别对红、绿、蓝3个波段的色彩进行采样。采样后的信号传送至大脑后组合…

色彩深度、位深度、8位图像、16位图像、24位图像

在数字图像处理中&#xff0c;平时所说的1位图像、8位图像、16位图像、24位图像、32位图像等&#xff0c;其中的“位”是指图像中每一个像素点的色彩深度&#xff0c;或位深度。 在处理数字图像中的颜色时&#xff0c;计算机实际上是用每个像素点需要的**色彩深度&#xff08;位…

微信小程序客服系统

微信公众平台 点击 客服 添加 微信文档-接收消息和事件 在页面中使用 第三方客服系统 芝麻小客服 填写对应的 appid && AppSecret 等信息 微信文档-接收消息和事件 在页面中使用 请点赞&#xff01;因为你的鼓励是我写作的最大动力&#xff01; 吹逼交流群&…

怎么授权接入芝麻小程序客服系统?

简单四步接入芝麻小客服,轻松上手小程序客服系统! 第一步:点击一键接入 第二步:选择小程序,选择授权接入 第三步:使用小程序管理员的微信扫码授权 请注意:小程序管理员不是公众号管理员,小程序的管理员账号是独立的。

芝麻小程序码基于设计原理提供免费美化小程序码

芝麻小程序码&#xff08;官网首发美化&#xff09;基于微信小程序码的设计原理&#xff0c;为小程序的开发、设计、运营人员提供免费的美化小程序码服务&#xff0c;助力小程序的运营推广和产品价值的体现。 先释放几个案列图片出来&#xff1a; 2017年4月份&#xff0c;微信…

scrapy框架下设置代理ip

问题&#xff1a;在使用框架进行爬取的时候报了405错误 解决方法&#xff1a; 使用芝麻代理ip在框架中进行设置 1.先在芝麻代理ip中进行注册 2.联系客服会给你充值让进行测试 3.点击生成api 4.在自己爬虫的middleware中加入代理类 5.在settings文件中进行配置&#xff0c;…

小程序客服关闭自动回复功能后如何解决关注公众号

进入小程序管理后台&#xff0c;小程序的客服的自动打开客服消息被关闭了 这个功能被很多人用来引导关注公众号&#xff0c;或者引导添加个人微信&#xff0c;那这个功能被封闭后&#xff0c;怎么办呢&#xff1f; 只能设置自动回复功能了。 芝麻小客服 http://xiaokefu.com.…

微信小程序客服可以直接在手机回复吗,小程序客服功能怎么用手机回复,微信小程序客服手机版

如题&#xff0c;很多小伙伴问过这个问题&#xff0c;答案是可以的。而且&#xff0c;这个解决方式是用小程序来解决&#xff0c;完全不需用下APP&#xff0c;真正地在一款小程序上处理多个小程序客服消息&#xff01; 一、在没有账号之前&#xff0c;支持抢先体验&#xff01;…

小程序客服消息

看到很多小程序里&#xff0c;点客服&#xff0c;提示关注公众号&#xff0c;比如制作器里这个功能&#xff0c;能够自动引导关注公众号&#xff0c;图文体验非常好&#xff0c;研究了小程序客服接口后&#xff0c;我们就自己把它做成一个工具了&#xff0c;方便小程序的运营人…

微信小程序-虚拟支付的解决方案!原来还可以这么玩!

什么是虚拟支付&#xff1f;比如购买非实物&#xff08;VIP会员、充值、课程、虚拟物品等&#xff09; 这次虚拟支付的整改&#xff0c;最受影响的应该就是那些知识付费、购买课程、在线教育之类的小程序 而这次整改&#xff0c;只针对于ios系统的小程序&#xff0c;安卓系统…