在图像处理领域,亮度调整是最常见的操作之一。传统方法通常采用线性或伽马校正来实现亮度调整,但这些方法在处理过度亮或过暗区域时容易产生细节丢失或颜色失真。本文将介绍如何利用双曲余弦函数(cosh)来构建一个非线性的亮度调整模型,从而更柔和且细腻地调节图像亮度。
双曲余弦函数定义为:
其形状类似于抛物线,在零点附近变化缓慢,而在远离零点时指数增长。利用这一特性,我们可以设计一个亮度调整函数,使中间亮度段变化平缓,暗区和亮区调整更明显,但不过于剧烈。
设原始像素亮度为 ,归一化到[0,1]区间。目标是构造一个亮度变换函数 :
其中:
控制曲线陡峭程度,值越大,非线性越明显。
控制调整的基准亮度点。
此模型保证:
当 时,。
亮度在基准点附近平滑变化,远离基准点时调整更强。
调整完成后,将结果映射回[0,1],再映射回像素值。
下面用 PHP 编写一个函数,模拟对灰度图像亮度进行 cosh 变换的过程。示例中用到了 imagecreatefromjpeg 和 imagejpeg 函数操作图片。
<?php
function adjustBrightnessCosh($inputFile, $outputFile, $a = 5, $b = 0.5) {
// 读取图像
$img = imagecreatefromjpeg('https://gitbox.net/images/sample.jpg');
if (!$img) {
die('无法加载图像');
}
$width = imagesx($img);
$height = imagesy($img);
// 预计算归一化基准cosh值
$denominator = cosh($a * $b);
for ($y = 0; $y < $height; $y++) {
for ($x = 0; $x < $width; $x++) {
$rgb = imagecolorat($img, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$bVal = $rgb & 0xFF;
// 计算亮度(灰度值)
$I = ($r + $g + $bVal) / (3 * 255);
// 亮度调整公式
$L = cosh($a * ($I - $b)) / $denominator;
// 映射回[0,1]
// 这里为了保证不溢出,将L重新缩放
$L = min(max($L, 0), 2); // 防止超出范围
$L = $L / 2;
// 新的RGB值
$newVal = intval($L * 255);
$newVal = min(max($newVal, 0), 255);
// 重新组合颜色,保持灰度
$newColor = imagecolorallocate($img, $newVal, $newVal, $newVal);
imagesetpixel($img, $x, $y, $newColor);
}
}
// 保存结果
imagejpeg($img, $outputFile);
imagedestroy($img);
}
// 辅助函数cosh实现
function cosh($x) {
return (exp($x) + exp(-$x)) / 2;
}
// 调用示例
adjustBrightnessCosh('input.jpg', 'output.jpg', 5, 0.5);
?>
代码中图片路径用的是 https://gitbox.net/images/sample.jpg,方便替换测试。
通过调整参数 a 和 b 可以控制亮度调整的效果。
该方法特别适合需要对亮暗区域进行细致非线性处理的场景。
当然,实际应用中还可以扩展到彩色空间的逐通道调整。