【发布时间】:2017-01-23 10:02:55
【问题描述】:
我需要在 C++ 中实现用于调整图像级别的算法,该算法类似于 Photoshop 或 GIMP 中的级别功能。 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);
【问题讨论】:
-
请向我们展示您到目前为止所做的尝试。首先,您应该熟悉如何 图像的组织方式(RGB 通道)以及可以对它们执行的基本操作。 Stack Overflow 不是代码编写服务,但如果您至少尝试自己解决问题,人们愿意帮助您。请阅读How to create a Minimal, Complete, and Verifiable example 和How do I ask a good question?。然后,更新并改进您的问题。
-
我熟悉图像表示、使用 OpenCV 加载图像、操作图像通道等。这不是一个问题。问题是图像转换算法。我不是要求为我编写任何代码。相反,我要求帮助我查找有关算法的信息。有了它,我就可以自己编写代码了。
-
我已经用我现在的代码更新了帖子。代码背后的想法很简单,它计算查找表并将其应用于图像。但是图像被覆盖了,而不是我在同一图像上使用 GIMP 获得相同的输入值。所以我试图理解我做错了什么,可能整个我当前的实现都是基于如何计算查找表的错误想法,所以这就是为什么我要询问正确的算法,而不是代码(即它的实现)。
标签: c++ algorithm image-processing