OpenCV视频链接

知识点

理论;
代码演示;

理论

图像变换可以分为点操作和区域操作,区域操作用于做图像卷积,特征提取,角点检测,平滑…;点操作即像素变换,直接操作像素,调整图像亮度和对比度属于像素变换-点操作;

f(i,j)----输入图像像素点;
g(i,j)----输出图像像素点;
α----增益变量,α越大,亮度,对比度越强;
常见的RGB数据格式,像素值(0-255)(tif等格式像素可能小于0);
亮度即灰度,亮度越大,灰度值越大(0最黑,255最白)

API

//创建一张与原图像大小和类型一致的空白图像,像素值初始化为0
Mat new_image = Mat::zeros(image.size(),image.type());
//确保RGB像素值在正确范围内
saturate_cast<uchar>(value);
//给每个像素点每个通道赋值
Mat.at<Vec3b>(x,y)[index] = value;

Demo

编程实现对每个像素点的线性变换操作

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
   
	Mat src, dst;

	src = imread("C:\\Users\\hello\\Desktop\\2.jpg");
	if (!src.data)
	{
   
		cout << "could not load the image" << endl;
		return - 1;
	}
	cvtColor(src, src, CV_BGR2GRAY); //转换色彩空间为灰度图像

	char input_win[] = "input image";
	namedWindow(input_win, CV_WINDOW_AUTOSIZE);
	imshow(input_win, src);

	int height = src.rows;
	int width = src.cols;

	dst = Mat::zeros(src.size(), src.type()); //创建一个空白图像
	float alpha = 1.2;
	float beta = 30;

	Mat m1;
	src.convertTo(m1, CV_32F); // 转换数据类型

	for (int row = 0; row < height; row++)
	{
   
		for (int col = 0; col < width; col++)
		{
   
			//判断是单通道还是多通道
			if (src.channels() == 3)
			{
   
				float b = m1.at<Vec3f>(row, col)[0];  //blue
				float g = m1.at<Vec3f>(row, col)[1];  //green
				float r = m1.at<Vec3f>(row, col)[2];  //red
				//调整图像亮度,对比度
				dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(alpha * b + beta);
				dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(alpha * g + beta);
				dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(alpha * r + beta); //保证像素在合理范围内

			}
			else if(src.channels() == 1)
			{
   
				float v = src.at<uchar>(row, col);
				dst.at<uchar>(row, col) = saturate_cast<uchar>(alpha * v + beta);
			}
		}
	}
	char output_title[] = "contrast and brightness change demo";

	namedWindow(output_title, CV_WINDOW_AUTOSIZE);
	imshow(output_title, dst);
	waitKey(0);
	return 0;
}

效果