gpt4 book ai didi

c++ - 图像电平调整算法

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:29:44 24 4
gpt4 key购买 nike

我需要在 C++ 中实现调整图像级别的算法,其工作方式类似于 Photoshop 或 GIMP 中的 Levels 功能。 IE。输入是:要调整的颜色 RGB 图像调整,同时点、黑点、中间调点、输出值。但我还没有找到任何关于如何执行此调整的信息。可能有人推荐我学习算法描述或资料。

目前我已经自己想出了以下代码,但它没有给出预期的结果,类似于我所看到的,例如在 GIMP 中,图像变得太亮了。下面是我当前的代码片段:

const int normalBlackPoint = 0;
const int normalMidtonePoint = 127;
const int normalWhitePoint = 255;
const double normalLowRange = normalMidtonePoint - normalBlackPoint + 1;
const double normalHighRange = normalWhitePoint - normalMidtonePoint;

int blackPoint = 53;
int midtonePoint = 110;
int whitePoint = 168;
int outputFrom = 0;
int outputTo = 255;

double outputRange = outputTo - outputFrom + 1;
double lowRange = midtonePoint - blackPoint + 1;
double highRange = whitePoint - midtonePoint;
double fullRange = whitePoint - blackPoint + 1;
double lowPart = lowRange / fullRange;
double highPart = highRange / fullRange;

int dim(256);
cv::Mat lut(1, &dim, CV_8U);
for(int i = 0; i < 256; ++i)
{
double p = i > normalMidtonePoint
? (static_cast<double>(i - normalMidtonePoint) / normalHighRange) * highRange * highPart + lowPart
: (static_cast<double>(i + 1) / normalLowRange) * lowRange * lowPart;
int v = static_cast<int>(outputRange * p ) + outputFrom - 1;
if(v < 0) v = 0;
else if(v > 255) v = 255;
lut.at<uchar>(i) = v;
}


....

cv::Mat sourceImage = cv::imread(inputFileName, CV_LOAD_IMAGE_COLOR);
if(!sourceImage.data)
{
std::cerr << "Error: couldn't load image " << inputFileName << "." << std::endl;
continue;
}


#if 0
const int forwardConversion = CV_BGR2YUV;
const int reverseConversion = CV_YUV2BGR;
#else
const int forwardConversion = CV_BGR2Lab;
const int reverseConversion = CV_Lab2BGR;
#endif

cv::Mat convertedImage;
cv::cvtColor(sourceImage, convertedImage, forwardConversion);

// Extract the L channel
std::vector<cv::Mat> convertedPlanes(3);
cv::split(convertedImage, convertedPlanes);

cv::LUT(convertedPlanes[0], lut, convertedPlanes[0]);

//dst.copyTo(convertedPlanes[0]);
cv::merge(convertedPlanes, convertedImage);

cv::Mat resImage;
cv::cvtColor(convertedImage, resImage, reverseConversion);
cv::imwrite(outputFileName, resImage);

最佳答案

Photoshop 色阶调整的伪代码

首先,计算用于中间调调整的 Gamma 校正值(如果需要)。下面粗略地模拟了 Photoshop 的技术,它对中间调值 0-128 应用 gamma 9.99-1.00,对 128-255 应用 1.00-0.01。

应用 Gamma 校正:

Gamma = 1
MidtoneNormal = Midtones / 255
If Midtones < 128 Then
MidtoneNormal = MidtoneNormal * 2
Gamma = 1 + ( 9 * ( 1 - MidtoneNormal ) )
Gamma = Min( Gamma, 9.99 )
Else If Midtones > 128 Then
MidtoneNormal = ( MidtoneNormal * 2 ) - 1
Gamma = 1 - MidtoneNormal
Gamma = Max( Gamma, 0.01 )
End If
GammaCorrection = 1 / Gamma

然后,对于每个像素的每个 channel 值 R、G、B (0-255),按顺序执行以下操作。

应用输入级别:

ChannelValue = 255 * ( ( ChannelValue - ShadowValue ) / 
( HighlightValue - ShadowValue ) )

应用中间调:

If Midtones <> 128 Then
ChannelValue = 255 * ( Pow( ( ChannelValue / 255 ), GammaCorrection ) )
End If

应用输出级别:

ChannelValue = ( ChannelValue / 255 ) *
( OutHighlightValue - OutShadowValue ) + OutShadowValue

地点:

  • 所有 channel 和调整参数值都是整数,包括 0-255
  • Shadow/Midtone/HighlightValue 是输入调整值(默认 0、128、255)
  • OutShadow/HighlightValue 为输出调整值(默认 0、255)
  • 您应该优化事物并确保值保持在范围内(例如每个 channel 为 0-255)

为了更准确地模拟 Photoshop,如果中间调 < 128,您可以使用非线性插值曲线。默认情况下,Photoshop 还会切掉最暗和最亮的 0.1% 的值。

关于c++ - 图像电平调整算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39510072/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com