- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我需要在 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);
最佳答案
首先,计算用于中间调调整的 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
地点:
为了更准确地模拟 Photoshop,如果中间调 < 128,您可以使用非线性插值曲线。默认情况下,Photoshop 还会切掉最暗和最亮的 0.1% 的值。
关于c++ - 图像电平调整算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39510072/
我的音频分析功能在 iPad (2) 上的响应比在 iPhone (4) 上的响应更好。它似乎对 iPad 上更柔和的声音很敏感,而 iPhone 需要更大声的输入才能正确响应。无论这是因为麦克风放置
我试图像这样在 Android 上获取麦克风的振幅电平: MediaRecorder recorder = new MediaRecorder(); recorder.setAudioSource(M
我想知道我的手机的tx level。我有一个 AT 命令终端,我只想要 AT 命令来获取 tx level。 我尝试了这个命令: AT*PSENGI=2 但是调制解调器返回: Error 此命令还返回
我真的很想看到一个独占模式音频应用程序的明确示例,该应用程序在一定的输入电平(音量)下从线路输入(不是麦克风)获取输入,并尽最大努力实现这一目标。 (首选 C++,但有总比没有好) 这听起来应该很简单
我正在构建一个 dB 计作为我正在创建的应用程序的一部分,我已经从我的 iPhone 上的麦克风接收峰值和平均功率(值范围从 -60 到 0.4),现在我需要弄清楚如何将这些功率级别转换为类似于此图表
我是一名优秀的程序员,十分优秀!