图像变换可以看作如下:
- 像素变换 – 点操作
- 邻域操作 – 区域
调整图像亮度和对比度属于像素变换-点操作
理论公式:
案列中需要用到的API
Mat new_image = Mat::zeros( image.size(), image.type() );
创建一张跟原图像大小和类型一致的空白图像、像素值初始化为0
saturate_cast<uchar>(value)
确保值大小范围为0~255之间
Mat.at<Vec3b>(y,x)[index]=value
给每个像素点每个通道赋值[C++] 纯文本查看 复制代码 /*
注意:
src.at<Vec3b>
src.at<Vec3f>
在使用浮点<Vec3f>修改时,前途必须通过转换类型函数进行转换,如果类型不匹配程序会报错
浮点型修改的好处是 它处理后将保留更加精确的数值,画质更加精确细腻
*/
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
#define IS_float_mode 1 //参数为1时 ,<Vec3f> 处理图片
int main(int argc, char** argv) {
Mat src, dst,src32f;
src = imread("D:/IDE/opencv-3.1.0/demo.jpg");
if (!src.data) {
printf("加载图片异常\n");
return -1;
}
int height = src.rows;
int width = src.cols;
dst = Mat::zeros(src.size(), src.type());
//创建等于SRC高宽 0空图片
float alpha = 1.5;
//对比度
float beta = 10;
//亮度
////////////////////////////////////////////////////////
#if(IS_float_mode==1)
{
src.convertTo(src32f, CV_32F);
}
#else
{
}
#endif
/////////////////////////////////////////////////////////////
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
//遍历像素值
if (src.channels() == 3)//3通道
{
#if(IS_float_mode==1)
{
float b = src32f.at<Vec3f>(y, x)[0];
float g = src32f.at<Vec3f>(y, x)[1];
float r = src32f.at<Vec3f>(y, x)[2];
dst.at<Vec3b>(y, x)[0] = saturate_cast<uchar>(b * alpha + beta);
dst.at<Vec3b>(y, x)[1] = saturate_cast<uchar>(g * alpha + beta);
dst.at<Vec3b>(y, x)[2] = saturate_cast<uchar>(r * alpha + beta);
//套用公式,修改像素数值
}
#else
{
float b = src.at<Vec3b>(y, x)[0];
float g = src.at<Vec3b>(y, x)[1];
float r = src.at<Vec3b>(y, x)[2];
dst.at<Vec3b>(y, x)[0] = saturate_cast<uchar>(b * alpha + beta);
dst.at<Vec3b>(y, x)[1] = saturate_cast<uchar>(g * alpha + beta);
dst.at<Vec3b>(y, x)[2] = saturate_cast<uchar>(r * alpha + beta);
//套用公式,修改像素数值
}
#endif
}
else if (src.channels() == 1)//单通道
{
float pix = src.at<uchar>(y, x);
dst.at<uchar>(y, x) = saturate_cast<uchar>(pix * alpha + beta);
//套用公式,修改像素数值
}
}
}
namedWindow("原图", CV_WINDOW_AUTOSIZE);
imshow("原图", src);
namedWindow("输出效果", CV_WINDOW_AUTOSIZE);
imshow("输出效果", dst);
waitKey(0);
return 0;
}
|