改变图像的亮度
代码
先上代码。
我自学的方式是先看代码,然后在代码中遇到不懂的再逐个查询资料,深入学习,直到学懂。大家按照符合自己的方式学习就好了,适合自己的才是最好的。共勉。
这里使得图像变亮/变暗仅仅是改变了alpha的值(alpha>1 变亮 alpha <1 变暗)。所以变亮和变暗的两段代码一样。
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
Mat src, dst1, dst2;
src = imread("E:/minions.jpg");
if (src.empty())//如果图像读取失败,输出error,返回-1
{
cout << "error" << endl;
return -1;
}
namedWindow("原图", WINDOW_AUTOSIZE);//创建一个窗口,并设置窗口大小为根据图片自适应
imshow("原图", src);//显示图像src
//分别获取源图像的高和宽
int height = src.rows;
int width = src.cols;
//定义dst1的高和宽、类型均与源图像src一致
dst1 = Mat::zeros(src.size(), src.type());
float alpha = 1.5;//大于1 变亮 小于1 变暗
float beta = 30;//是增量
for(int row=0;row<height;row++)
for (int col = 0; col < width; col++)
{
if (src.channels() == 3)
{
float b = src.at<Vec3b>(row, col)[0];///bgr 分别为Vec3b的blue、green、red
float g = src.at<Vec3b>(row, col)[1];
float r = src.at<Vec3b>(row, col)[2];
dst1.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b * alpha + beta);///对dst的bgr分别进行RGB的增值 使用saturate_cast来去确保RGB在0-255之间
dst1.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g * alpha + beta);
dst1.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r * alpha + beta);
}
else if(src.channels() == 1)
{
float v = src.at<uchar>(row,col);
dst1.at<uchar>(row, col) = saturate_cast<uchar>(v * alpha + beta);
}
}
namedWindow("变亮", WINDOW_AUTOSIZE);
imshow("变亮", dst1);
dst2 = Mat::zeros(src.size(), src.type());
alpha = 0.5;//大于1 变亮 小于1 变暗
beta = 30;//是增量
for (int row = 0; row < height; row++)
for (int col = 0; col < width; col++)
{
if (src.channels() == 3)
{
float b = src.at<Vec3b>(row, col)[0];///bgr 分别为Vec3b的blue、green、red
float g = src.at<Vec3b>(row, col)[1];
float r = src.at<Vec3b>(row, col)[2];
dst2.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b * alpha + beta);///对dst的bgr分别进行RGB的增值 使用saturate_cast来去确保RGB在0-255之间
dst2.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g * alpha + beta);
dst2.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r * alpha + beta);
}
else if (src.channels() == 1)
{
float v = src.at<uchar>(row, col);
dst2.at<uchar>(row, col) = saturate_cast<uchar>(v * alpha + beta);
}
}
namedWindow("变暗", WINDOW_AUTOSIZE);
imshow("变暗", dst2);
waitKey(0);
return 0;
}
图像变换
图像变换有两种:
- 像素变换(点操作);
- 邻域变换(区域操作),包括卷积、平滑、模糊、交点检测等;
调整图像的亮度和对比度属于像素变换,公式为:
g=b*alpha+beta
b是源图像的某点的像素值,beta为增量。
代码解释
之前已经解释过具体功能的代码就不进行解释了,如果想了解的话可以看下我之前的文章,毕竟咱们是在不断学习的过程中,要牢记旧知识,不断学习新知识。
float b = src.at<Vec3b>(row, col)[0];
float g = src.at<Vec3b>(row, col)[1];
float r = src.at<Vec3b>(row, col)[2];
Vec3b对应3通道的blue、green、red的uchar类型,与之类似的还有Vec3f等。
//实现的功能是对dst2的各个通道(b、g、r)分别进行RGB增值
dst2.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b * alpha + beta);
dst2.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g * alpha + beta);
dst2.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r * alpha + beta);
satueate_cast(x)函数是确保x的RGB值在0–255之间,若x的RGB值小于0,返回0;若x的RGB值大于255,返回255;若x的RGB值在[0,255],则返回对应的RGB值。
各种处理后的结果图片对比:
源图像经过变亮和变暗操作后的结果。
这篇opencv的学习笔记就这样结束了。
我是一个初学者,如果有相关的问题大家可以评论提出一起讨论,或指出我的错误之处,大家一起学习,一起进步,谢谢啦。