图像亮度变换

引言

图像处理中,亮度变换指图像在空域上的点运算,通常包括图像增强,亮度/对比度调节,GAMMA值调节各直方图调整等。如何进行图像GAMMA值调节,我们可以参考Matlab中函数imadjust.m理解其原理,然后,使用OpenCV实现与函数imadjust一样功能,进行图像亮度变换实现。

基本理论

亮度变换的原理可以参考Matlab中函数imadjust.m.首先,在imadjust中,参数gamma指明了由f 映射生成图像g 时曲线的形状。如果gamma的值小于1,映射被加权至较高(较亮)的输出值,如图3.2(a)所示。如果gamma的值大于1,映射被加权至较低(较暗)的输出值,如图3.2(c)所示。如果省略函数参量,gamma默认为1(线性映射),如图3.2(b)所示。



imadjust函数和函数解析,如下所示:

=======(此内容来源于http://www.mathworks.cn/cn/help/images/ref/imadjust.html)=======

J = imadjust (I)
J = imadjust (I,[low_in;high_in])
J = imadjust (I,[low_in;high_in],[low_out;high_out])
J = imadjust (..., gamma)
newmap = imadjust (map, ...)
RGB_out = imadjust (RGB, ...)
Adjust image or colormap values to a specified range

J=imadjust(I) adjusts intensity imageI values so that 1% of data on lower and higher values (2% in total) of the image is saturated; choosing for that the corresponding lower and higher bounds (using stretchlim) and mapping them to 0 and 1. J is an image of the same size asI which contains mapped values. This is equivalent toimadjust(I,stretchlim(I)).

J=imadjust(I,[low_in;high_in]) behaves as described butuses low_in andhigh_in values instead of calculating them. It maps those values to 0 and 1; saturates values lower than first limit to 0 and values higher than second to 1; and finally maps all values between limits linearly to a value between 0 and 1. If[] is passes as[low_in;high_in] value, then[0;1] is taken as a default value.

J=imadjust(I,[low_in;high_in],[low_out;high_out]) behaves as described butmaps output values betweenlow_out and high_out instead of 0 and 1. A default value[] can also be used for this parameter, which is taken as[0;1].

J=imadjust(...,gamma) takes, in addition of 3 parameters explained above, an extra parametergamma, which specifies the shape of the mapping curve between input elements and output elements, which is linear (as taken if this parameter is omitted). If gamma is above 1, then function is weighted towards lower values, and if below 1, towards higher values.

newmap=imadjust(map,...) applies a transformation to a color mapmap, which output isnew map. This transformation is the same as explained above, just using a map instead of an image.low_in,high_in,low_out,high_out and gamma can be scalars, in which case the same values are applied for all three color components of a map; or it can be 1-by-3vectors, to define unique mappings for each component.

RGB_out=imadjust(RGB,...) adjust RGB imageRGB (aM-by-N-by-3 array) the same way as specified in images and color maps. Here too low_in,high_in,low_out,high_out and gamma can be scalars or 1-by-3 matrices, to specify the same mapping for all planes, or unique mappings for each.

The formula used to realize the mapping (if we omit saturation) is:

J = low_out +(high_out - low_out).* ((I - low_in)/(high_in - low_in)).^ gamma
Compatibility notes:

  • Prior versions of imadjust allowed [low_in; high_in] and[low_out; high_out] to be row vectors. Compatibility with this behaviour has been keeped, although preferred form is vertical vector(since it extends nicely to 2-by-3 matrices for RGB images and colormaps).
  • Previous version of imadjust, if low_in>high_in it "negated" output. Now it is negated iflow_out>high_out, for compatibility withMATLAB.
  • Class of I is not considered, so limit values are not modified depending on class of the image, just treated "as is". When Octave 2.1.58 is out, limits will be multiplied by 255 for uint8images and by 65535 for uint16 as in MATLAB.
=======================================================================================

通过上述对imadjust函数解析,可以理解为:图像的亮度和对比度调节就是一种亮度变换,可以通过直接调整[low_in,high_in]和[low_out,high_out]的数值来实现亮度以及对比度

在Matlab上使用imadjust实现图像亮度变换比较简单,参考代码和输出结果效果所示:

I = imread('test.jpg');
J = imadjust(I,[0,0.5],[0.5,1]);
imshow(I);
figure,imshow(J);
输出结果

   

(a)源始图像     (b)用MATLAB中函数imadjust得到的图像亮度变换

现在,在OpenCV中,定义ImageAdjust函数来实现图像亮度变换功能,其中参数:src为原始图像输入;dst为输出图像。low_in,high_in,low_out,high_out与Matlob中imadjust函数的参数是相似的。贴出此函数代码,仅作参考。

参考代码

IplImage* ImageTrans::ImageAdjust(IplImage *src, IplImage *dst,
          double low_in, double high_in,
          double low_out, double high_out, double gamma )
{
    double low2 = low_in*255;
    double high2 = high_in*255;
    double bottom2 = low_out*255;
    double top2 = high_out*255;
    double err_in = high2 - low2;
    double err_out = top2 - bottom2;

    int x,y;
    double val0,val1,val2;

    // intensity transform
    for( y = 0; y < src->height; y++) {
        for (x = 0; x < src->width; x++){
            val0 = ((uchar*)(src->imageData+src->widthStep*y))[x*src->nChannels]; 
            val0 = pow((val0 - low2)/err_in,gamma)*err_out+bottom2;
            if(val0>255) val0=255; 
	    if(val0<0) val0=0; 
	    ((uchar*)(dst->imageData+dst->widthStep*y))[x*src->nChannels]=(uchar)val0;

	    val1 = ((uchar*)(src->imageData+src->widthStep*y))[x*src->nChannels+1]; 
            val1 = pow((val1- low2)/err_in, gamma)*err_out+bottom2;
            if(val1>255) val1=255; 
            if(val1<0) val1=0;
	    ((uchar*)(dst->imageData+dst->widthStep*y))[x*src->nChannels+1]=(uchar)val1;

	    val2 = ((uchar*)(src->imageData + src->widthStep*y))[x*src->nChannels+2]; 
            val2 = pow((val1-low2)/err_in,gamma)*err_out+bottom2;
            if(val2>255) val2=255; 
	    if(val2<0) val2=0; // Make sure src is in the range [low,high]
	    ((uchar*)(dst->imageData+dst->widthStep*y))[x*src->nChannels+2]=(uchar)val2;
        }
    }
    return 0;
}
测试输出结果效果:


(a)源始图像     (b)用程序ImageAdjust得到的图像亮度变换


(c)源始图像    (d)用程序ImageAdjust得到的图像亮度变换


关于Image Engineering & Computer Vision的更多讨论与交流,敬请关注本博和新浪微博songzi_tea.


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值