更改图像的对比度和亮度

目标:

在这个教程中你将学会如何去:

获取像素值;

用0去初始化一个矩阵;

Saturate_cast是做什么的以及为什么它很有用;

得到像素转换的一些参数;

理论:

图像处理:

一般通用的图像处理操作是这样一个函数:有一个或多个输入并且产生一个输出图像;

图像变换可以被看作:

         点操作(像素转换);

         领域操作(基于区域的);

像素转换:

         在这种图像处理转换中,每一个输出像素的值取决于相应的输入的像素值;

         这种操作的例子包括亮度和对比度的调整,以及颜色的修正和转换;

亮度和对比度的调整:

         两种比较常用的点操作就是乘法以及和加上一个常数:


参数阿尔法大于零并且贝塔通常被称为增益以及偏差;有时这些参数被叫做控制相对地控制对比度和亮度的参数。

你可以认为f(X)是源操作图像,g(x)是输出图像。然后,更方便地,我们可以把表达式写成:


在这里,I,j表示第i行和第j列的像素值。

 

代码:

         下面的代码就是应用上述的公式:

/***************************************************
******		Translator:York
******		Email:y_zhou1991@163.com
******		Date:2016/03/02
*****************************************************/

#include <cv.h>
#include <highgui.h>
#include <iostream>

using namespace cv;

double alpha; /**< Simple contrast control */
int beta;  /**< Simple brightness control */

int main(int argc, char** argv)
{
	/// Read image given by user
	Mat image = imread("F:/Photo/OpenCV_Photo/baboon.jpg");
	Mat new_image = Mat::zeros(image.size(), image.type());

	/// Initialize values
	std::cout << " Basic Linear Transforms " << std::endl;
	std::cout << "-------------------------" << std::endl;
	std::cout << "* Enter the alpha value [1.0-3.0]: "; std::cin >> alpha;
	std::cout << "* Enter the beta value [0-100]: "; std::cin >> beta;

	/// Do the operation new_image(i,j) = alpha*image(i,j) + beta
	for (int y = 0; y < image.rows; y++)
	{
		for (int x = 0; x < image.cols; x++)
		{
			for (int c = 0; c < 3; c++)
			{
				new_image.at<Vec3b>(y, x)[c] =
					saturate_cast<uchar>(alpha*(image.at<Vec3b>(y, x)[c]) + beta);
			}
		}
	}

	/// Create Windows
	namedWindow("Original Image", 1);
	namedWindow("New Image", 1);

	/// Show stuff
	imshow("Original Image", image);
	imshow("New Image", new_image);

	/// Wait until user press some key
	waitKey();
	return 0;
}

解释:

1、  我们通过创建参数让用户输入阿尔法和β来保存:

2、  使用imread载入图像,并且把它保存在一个Mat对象中:

3、  现在,因为我们将要对这幅图像做一些变换,所以我们需要一个新的Mat对象来保存它。同时,我们想要它具有以下特征:

a)        以0来初始化Mat对象;

b)        和源图像保持同样的尺寸和类型;

4、  现在,就是去应用最开始的那个公式去得到每一个像素值。因为我们是处理BGR图像,每一个像素我们将有三个值(B,G和R),所以我们将单独得到这些值。就是用下面一段代码实现:

注意下面的一些事项:

           去得到图像中的每一个像素,我们使用这样的语法:image.at<Vec3b>(y,x)[c] ,其中y是行,x是列,c是R,G或B(0,1或2).

因为

这个操作计算的结果可能超出整数的范围,我们可以使用saturate_cast来确保这个值是有效的。

1、 最后,我们创建窗口来显示图像。

注意:除了使用for循环来遍历每一个像素,我们还可以有一种更简单的命令:

image.convertTo(new_image, -1, alpha, beta);

这个函数就是这个公式:new_image = a*image + beta。然而,之所以用上面的方法是像让你知道如何去遍历每一个像素。在任何情况下,两个方法都是得到同样的结果,然而convertTo函数却更加地有效率且是经过优化了的。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值