系列文章目录
前言
本篇介绍如何调整图像亮度和对比度的方法,效果等价于美图app中的小功能,目测不止这几种方式,持续更新!
一、像素值计算
通过对每个点的像素值进行加减计算,达到调整图片亮度的目的,示例代码如下:
// 增加亮度方法一
void IncreaseBrightness1(int iPos, void* pUserdata)
{
Mat img = ((Mat*)pUserdata)->clone();
int iWidth = img.cols;
int iHeight = img.rows;
int iChannels = img.channels();
// 直接挨个像素点加上某个值
for (int row = 0; row < iHeight; row++)
{
// 可以指针偏移,也可用使用数组下标访问
uchar* pCurRow = img.ptr<uchar>(row);
for (int col = 0; col < iWidth; col++)
{
if (iChannels == 1)
{
*pCurRow++ = saturate_cast<uchar>(*pCurRow + iPos);
}
else if (iChannels == 3)
{
// saturate_cast 防止颜色溢出操作;像素值小于0时,赋值0;大于255时,赋值255
*pCurRow++ = saturate_cast<uchar>(*pCurRow + iPos);
*pCurRow++ = saturate_cast<uchar>(*pCurRow + iPos);
*pCurRow++ = saturate_cast<uchar>(*pCurRow + iPos);
}
}
}
imshow(g_pOutputWinTitle, img);
}
二、使用cv::add
使用cv::add等API进行图像像素计算,实现图像对比度调整,示例代码如下:
// 增加亮度方法二
void IncreaseBrightness2(int iPos, void* pUserdata)
{
Mat img = ((Mat*)pUserdata)->clone();
Mat dst;
Mat src2 = Mat::zeros(img.size(), img.type());
src2 = Scalar(iPos, iPos, iPos);
// 功能:计算两个图像的像素值的和
// 参数:src1 第一个输入图像
// src2 第二个输入图像
// dst 与输入图像具有相同大小和通道数的输出图像;深度由dtype或src1/src2定义
// mask 可选操作掩码-8位单通道图像,指定要更改的输出图像元素。
// dtype 输出图像的可选深度,src1和src2深度相等时可设置值-1(默认)
add(img, src2, dst);
// 如果src1和src2深度相同,等价于
//dst = img + src2;
// 相减 subtract,参数列表同上,如果深度相同,等价于dst = src1 - src2;
// 相乘 multiply,参数列表同上,像素值之间的运算
// 相除 divide,参数列表同上,像素值之间的运算
imshow(g_pOutputWinTitle, dst);
}
三、使用cv::addWeighted
图像混合函数addWeighted不但可以调整亮度,还可以调整对比度,代码如下(示例):
// 增加 亮度/对比度 方法三
void IncreaseBrightness3(int iPos, void* pUserdata)
{
Mat img = ((Mat*)pUserdata)->clone();
// addWeighted的两张混合图像的大小和类型必须一致
Mat src2 = Mat::zeros(img.size(), img.type());
Mat dst;
/*******************************调整图像亮度**********************************/
// 使用图像混合函数(dst = src1*alpha + src2*beta + gamma;)
// 输入图像1权重为1,输入图像2的权重设置为0,增加gamma的值即可实现亮度调整
addWeighted(img, 1.0, src2, 0, iPos, dst);
imshow(g_pOutputWinTitle, dst);
/*******************************调整图像对比度**********************************/
// 使用图像混合函数(dst = src1*alpha + src2*beta + gamma;)
// 输入图像2的权重设置为0,gamma的值为0,修改输入图像1的权重、可实现对比度调整
//double dContrast = (double)iPos / 100.0;
//addWeighted(img, dContrast, src2, 0, 0, dst);
//imshow(g_pOutputWinTitle, dst);
}
四、主函数
代码如下(示例):
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using std::cout;
using std::endl;
char* g_pOutputWinTitle = "输出图像";
int g_iBrightnessValue1 = 30;
int g_iBrightnessValue2 = 30;
int g_iBrightnessValue3 = 30;
int g_iBrightnessMax = 255;
// 增加亮度方法一
void IncreaseBrightness1(int iPos, void* pUserdata);
// 增加亮度方法二
void IncreaseBrightness2(int iPos, void* pUserdata);
// 增加 亮度/对比度 方法三
void IncreaseBrightness3(int iPos, void* pUserdata);
int main(void)
{
Mat img = imread("E:\\2.png");
if (img.empty())
{
cout << "load image fail." << endl;
return -1;
}
imshow("输入图像", img);
namedWindow(g_pOutputWinTitle);
createTrackbar("亮度调整方法一", g_pOutputWinTitle, &g_iBrightnessValue1, g_iBrightnessMax, IncreaseBrightness1, (void*)&img);
createTrackbar("亮度调整方法二", g_pOutputWinTitle, &g_iBrightnessValue2, g_iBrightnessMax, IncreaseBrightness2, (void*)&img);
createTrackbar("亮度调整方法三", g_pOutputWinTitle, &g_iBrightnessValue3, g_iBrightnessMax, IncreaseBrightness3, (void*)&img);
IncreaseBrightness1(g_iBrightnessValue1, (void*)&img);
waitKey(0);
return 0;
}
总结
纯粹是学习道路上的一点记录,很多地方理解的不是很透彻,不足的地方欢迎指正,会一直完善!