OpenCV-图像明度
Posted 翟天保Steven
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV-图像明度相关的知识,希望对你有一定的参考价值。
作者:Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
实现原理
颜色所具有的亮度和暗度被称为图像明度。计算明度的基准是灰度测试卡。黑色为0,白色为10。色彩可以分为有彩色和无彩色,但后者仍然存在着明度。作为有彩色,每种色各自的亮度、暗度在灰度测试卡上都具有相应的位置值。彩度高的色对明度有很大的影响,不太容易辨别。在明亮的地方鉴别色的明度比较容易的,在暗的地方就难以鉴别。
明度调整可通过合成方式实现:若参数为正,则调整后的图像可以认为加了一层白色遮罩层,即原图像RGB数值×(1-alpha)+255*alpha;反之亦然,认为加了一层黑色遮罩层,即原图RGB*(1+alpha),其中alpha是负数。
明度调整算法的具体实现流程如下:
1.设置调整参数percent,取值为-100到100,类似PS中设置,归一化后为-1到1。
2.针对图像所有像素点单个处理。当percent大于等于0时,加上白色遮罩,调整后的RGB三通道数值为:
3.若percent小于0时,加上黑色遮罩,此时调整后的图像RGB三通道值为:
至此,图像实现了明度的调整,算法逻辑参考xingyanxiao。C++实现代码如下。
功能函数代码
// 明度
cv::Mat Lightness(cv::Mat src, float percent)
{
float alpha = percent / 100;
alpha = max(-1.f, min(1.f, alpha));
cv::Mat temp = src.clone();
int row = src.rows;
int col = src.cols;
for (int i = 0; i < row; ++i)
{
uchar *t = temp.ptr<uchar>(i);
uchar *s = src.ptr<uchar>(i);
for (int j = 0; j < col; ++j)
{
uchar b = s[3 * j];
uchar g = s[3 * j + 1];
uchar r = s[3 * j + 2];
if (alpha >= 0)
{
t[3 * j + 2] = static_cast<uchar>(r*(1 - alpha) + 255 * alpha);
t[3 * j + 1] = static_cast<uchar>(g*(1 - alpha) + 255 * alpha);
t[3 * j] = static_cast<uchar>(b*(1 - alpha) + 255 * alpha);
}
else
{
t[3 * j + 2] = static_cast<uchar>(r*(1 + alpha));
t[3 * j + 1] = static_cast<uchar>(g*(1 + alpha));
t[3 * j] = static_cast<uchar>(b*(1 + alpha));
}
}
}
return temp;
}
C++测试代码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
cv::Mat Lightness(cv::Mat src, float percent);
int main()
{
cv::Mat src = imread("1.jpg");
cv::Mat result = Lightness(src, 50.f);
imshow("original", src);
imshow("result", result);
waitKey(0);
return 0;
}
// 明度
cv::Mat Lightness(cv::Mat src, float percent)
{
float alpha = percent / 100;
alpha = max(-1.f, min(1.f, alpha));
cv::Mat temp = src.clone();
int row = src.rows;
int col = src.cols;
for (int i = 0; i < row; ++i)
{
uchar *t = temp.ptr<uchar>(i);
uchar *s = src.ptr<uchar>(i);
for (int j = 0; j < col; ++j)
{
uchar b = s[3 * j];
uchar g = s[3 * j + 1];
uchar r = s[3 * j + 2];
if (alpha >= 0)
{
t[3 * j + 2] = static_cast<uchar>(r*(1 - alpha) + 255 * alpha);
t[3 * j + 1] = static_cast<uchar>(g*(1 - alpha) + 255 * alpha);
t[3 * j] = static_cast<uchar>(b*(1 - alpha) + 255 * alpha);
}
else
{
t[3 * j + 2] = static_cast<uchar>(r*(1 + alpha));
t[3 * j + 1] = static_cast<uchar>(g*(1 + alpha));
t[3 * j] = static_cast<uchar>(b*(1 + alpha));
}
}
}
return temp;
}
测试效果
通过调整percent可以实现图像明度的调整。
如果函数有什么可以改进完善的地方,非常欢迎大家指出,一同进步何乐而不为呢~
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!
以上是关于OpenCV-图像明度的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV 例程200篇205. 调节色彩平衡/饱和度/明度