码迷,mamicode.com
首页 > 其他好文 > 详细

Opencv图像识别从零到精通(9)----对比度亮度改变

时间:2016-07-18 20:21:44      阅读:896      评论:0      收藏:0      [点我收藏+]

标签:

           一张图像来说,会有不同的亮暗程度,很多时候都要增强一下,增强的方法有很多,从大量可以说是线性变换和非线性变换,当然这是说空间域的,频率域的暂时不考虑。

线性变换增强,也是对点的操作,如下图

一、点操作,线性增强

  • 两种常用的点过程(即点算子),是用常数对点进行 乘法 和 加法 运算:

    技术分享

  • 两个参数 技术分享 和 技术分享 一般称作 增益 和 偏置 参数。我们往往用这两个参数来分别控制 对比度 和 亮度 。

  • 你可以把 技术分享 看成源图像像素,把 技术分享 看成输出图像像素。这样一来,上面的式子就能写得更清楚些:

    技术分享

    其中, 技术分享 和 技术分享 表示像素位于 第i行 和 第j列 

让我看看这个应用,核心就是上面的公式

<span style="font-size:18px;">#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace std;
using namespace cv;

double alpha; /**< 控制对比度 */
int beta;  /**< 控制亮度 */

int main( int argc, char** argv )
{
    /// 读入用户提供的图像
    Mat image = imread("lena.jpg" );
    Mat new_image = Mat::zeros( image.size(), image.type() );

    /// 初始化
    //cout << " Basic Linear Transforms " << endl;
    //cout << "-------------------------" << endl;
    //cout << "* Enter the alpha value [1.0-3.0]: ";
    //cin >> alpha;
    //cout << "* Enter the beta value [0-100]: ";
    //cin >> beta;
	int alpha=2;
	int beta=20;
    /// for循环执行运算 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 );
            }
        }
    }
    /// 创建窗口
    namedWindow("Original Image", 1);
    namedWindow("New Image", 1);

    /// 显示图像
    imshow("Original Image", image);
    imshow("New Image", new_image);

    /// 等待用户按键
    waitKey();
    return 0;
}</span>

技术分享

二、带滑动条的图像对比度增强

<span style="font-size:18px;">C++: int createTrackbar(conststring& trackbarname, conststring& winname,  
 int* value, int count, TrackbarCallback onChange=0,void* userdata=0);  </span>

  • 第一个参数,const string&类型的trackbarname,表示轨迹条的名字,用来代表我们创建的轨迹条。
  • 第二个参数,const string&类型的winname,填窗口的名字,表示这个轨迹条会依附到哪个窗口上,即对应namedWindow()创建窗口时填的某一个窗口名。
  • 第三个参数,int* 类型的value,一个指向整型的指针,表示滑块的位置。并且在创建时,滑块的初始位置就是该变量当前的值。
  • 第四个参数,int类型的count,表示滑块可以达到的最大位置的值。PS:滑块最小的位置的值始终为0。
  • 第五个参数,TrackbarCallback类型的onChange,首先注意他有默认值0。这是一个指向回调函数的指针,每次滑块位置改变时,这个函数都会进行回调。并且这个函数的原型必须为void XXXX(int,void*);其中第一个参数是轨迹条的位置,第二个参数是用户数据(看下面的第六个参数)。如果回调是NULL指针,表示没有回调函数的调用,仅第三个参数value有变化。
  • 第六个参数,void*类型的userdata,他也有默认值0。这个参数是用户传给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value实参是全局变量的话,完全可以不去管这个userdata参数。
<span style="font-size:18px;"> 
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>

using namespace std;
using namespace cv;

static void ContrastAndBright(int, void *);

int g_nContrastValue; //对比度值
int g_nBrightValue;  //亮度值
Mat g_srcImage,g_dstImage;

int main(   )
{

	g_srcImage = imread( "lena.jpg");
	g_dstImage = Mat::zeros( g_srcImage.size(), g_srcImage.type() );
	g_nContrastValue=80;
	g_nBrightValue=80;
	namedWindow("【效果图窗口】", 1);
	//创建轨迹条
	createTrackbar("对比度:", "【效果图窗口】",&g_nContrastValue, 300,ContrastAndBright );
	createTrackbar("亮   度:", "【效果图窗口】",&g_nBrightValue, 200,ContrastAndBright );
	//调用回调函数
	ContrastAndBright(g_nContrastValue,0);
	ContrastAndBright(g_nBrightValue,0);
	//输出一些帮助信息
	cout<<endl<<"\t运行成功,请调整滚动条观察图像效果\n\n"
		<<"\t按下“q”键时,程序退出\n";
	//按下“q”键时,程序退出
	while(char(waitKey(1)) != 'q') {}
	return 0;
}


static void ContrastAndBright(int, void *)
{

	namedWindow("【原始图窗口】", 1);
	// 三个for循环,执行运算 g_dstImage(i,j) = a*g_srcImage(i,j) + b
	for( int y = 0; y < g_srcImage.rows; y++ )
	{
		for( int x = 0; x < g_srcImage.cols; x++ )
		{
			for( int c = 0; c < 3; c++ )
			{
				g_dstImage.at<Vec3b>(y,x)[c] = saturate_cast<uchar>( (g_nContrastValue*0.01)*( g_srcImage.at<Vec3b>(y,x)[c] ) + g_nBrightValue );
			}
		}
	}
	// 显示图像
	imshow("【原始图窗口】", g_srcImage);
	imshow("【效果图窗口】", g_dstImage);
}

</span>

技术分享

三、Matlab辅助

      maltab中主要用的函数是imadjust()

      

<span style="font-size:18px;">J = imadjust(I,[low_in high_in],[low_out high_out])</span>

  • [low_in high_in]为原图象中要变换的灰度范围,
  • [low_out high_out]指定了变换后的灰度范围。

clear all;
I = imread('pout.tif');
J = imadjust(I);
subplot(1,4,1);imshow(I), 
xlabel('(a)原始图像')
subplot(1,4,2), imshow(J)
xlabel('(b)增强对比度所得图像')
K=imadjust(I,[0.4,0.8],[]);   %对指定的灰度范围进行图像增强处理
subplot(1,4,3), imshow(K)
xlabel('(c)指定对比度范围增强图像')
K1=imadjust(I,[],[0.4 0.6]);   %对指定的灰度范围进行图像增强处理
subplot(1,4,4), imshow(K1)
xlabel('(d)指定对比度范围增强图像')
K2=imadjust(I,[0.5 0.8],[],0.5);   %对指定的灰度范围进行图像增强处理
figure
imshow(K2)

技术分享


Opencv图像识别从零到精通(9)----对比度亮度改变

标签:

原文地址:http://blog.csdn.net/qq_20823641/article/details/51939827

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!