OpenCV之亮度、对比度详解

一、亮度和对比度调整的理论依据


首先我们给出算子的概念。一般的图像处理算子都是一个函数,它接受一个或多个输入图像,并产生输出图像。下式给出了算子的一般形式:


                                                  或者


今天我们所讲解的图像亮度和对比度的调整操作,其实属于图像处理变换中比较简单的一种——点操作(pointoperators)。点操作有一个特点,仅仅根据输入像素值(有时可加上某些全局信息或参数),来计算相应的输出像素值。这类算子包括亮度(brightness和对比度contrast调整,以及颜色校正(colorcorrection)和变换(transformations)。

 

最两种常用的点操作(或者说点算子),很显然,是乘上一个常数(对应对比度的调节)以及加上一个常数(对应亮度值的调节)。用公式表示出来就是这样:


            

 

看到这个式子,我们关于图像亮度和对比度调整的策略就呼之欲出了。


其中:

  • 参数f(x)表示源图像像素。
  • 参数g(x) 表示输出图像像素。
  • 参数a(需要满足a>0)被称为增益(gain),常常被用来控制图像的对比度。
  • 参数b通常被称为偏置(bias),常常被用来控制图像的亮度。

而更近一步,我们这样改写这个式子:


其中,i 和 j 表示像素位于第i行 和 第j列 。

那么,这个式子就可以用来作为我们在OpenCV中控制图像的亮度和对比度的理论公式,其实现方法可以通过addWeighted函数或for逐个访问图像像素实现。


例程:

// Bright_and_Contrast.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace std;
using namespace cv;

Mat srcImage;
int bright_init=1;
int contrast_init=1;

void bright_track(int,void*)
{
	Mat dstImage;
	//调用函数实现
	addWeighted(srcImage,1,srcImage,0,bright_init,dstImage);
	
	/************************************************************************/
	/* 
	访问图像中像素实现三个for循环,执行运算 new_image(i,j) =a*image(i,j) + b 
	Mat dstImage(srcImage.rows,srcImage.cols,srcImage.type());
	for(int y = 0; y < srcImage.rows; y++ )  
	{  
	for(int x = 0; x < srcImage.cols; x++ )  
	{  
	for(int c = 0; c < 3; c++ )  
	{  
	//使用saturate_cast防止像素值超值或者为浮点数
	dstImage.at<Vec3b>(y,x)[c]= saturate_cast<uchar>( (contrast_init*0.01)*(srcImage.at<Vec3b>(y,x)[c] ) + bright_init );  
	}  }  }                                                                 */
	/************************************************************************/ 
	
	imshow("Image",dstImage);
}
void contrast_track(int,void*)
{
	Mat dstImage;
	addWeighted(srcImage,contrast_init*0.02,srcImage,0,0,dstImage);

	/************************************************************************/
	/* 
	访问图像中像素实现三个for循环,执行运算 new_image(i,j) =a*image(i,j) + b 
	Mat dstImage(srcImage.rows,srcImage.cols,srcImage.type());
	for(int y = 0; y < srcImage.rows; y++ )  
	{  
	for(int x = 0; x < srcImage.cols; x++ )  
	{  
	for(int c = 0; c < 3; c++ )  
	{  
	//使用saturate_cast防止像素值溢出或者为浮点数
	dstImage.at<Vec3b>(y,x)[c]= saturate_cast<uchar>( (contrast_init*0.01)*(srcImage.at<Vec3b>(y,x)[c] ) + bright_init );  
	}  }  }                                                                 */
	/************************************************************************/ 

	imshow("Image",dstImage);
}

int _tmain(int argc, _TCHAR* argv[])
{
	srcImage=imread("1.jpg",1);
	if (srcImage.empty())
	{
		cout<<"读入文件错误"<<endl;
		return -1;
	}

	namedWindow("Image",CV_WINDOW_NORMAL);
	imshow("Image",srcImage);

	createTrackbar("亮度","Image",&bright_init,100,bright_track);
	createTrackbar("对比度","Image",&contrast_init,100,contrast_track);

	waitKey(0);
	return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值