原创 OpenCV统计应用-影像增强,亮度/对比实作

2009-2-22 00:00 4267 10 10 分类: 软件与OS

OpenCV统计应用-影像增强,亮度/对比实作 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


在一般显示屏幕以及图形处理的应用软件上,都会有一个亮度/对比的色彩(Brightness/Contrast)调整,它是属于影像增强的部份,OpenCV里面的Sample Code里面就有这样的灰阶程序的实作,在这边就修改了OpenCVSample Code,来做色彩增强的亮度/对比的程序,而在一般的亮度/对比来讲亮度(Brightness)的范围为0~200而对比(Contrast)亦是0~200,它们由一条线性函数的公式所定义,对比所代表的是斜率,亮度则是偏移量,这条线性公式代表的是Look-up table的对应,它的数学式定义如下

原始的亮度对比数值范围为-100~100之间,C代表对比,B代表亮度
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />b86b65db-07bd-4168-bc8e-0f7b21751d34.jpg

对于对比率(Contrast ratio)来讲,delta范围应该落在0~255,这边将对比率的公式做重新的调整
0c127f23-5e8f-407f-92cb-4c2c32cd24a2.jpg
3e0d7045-af28-462b-91ac-10b716f06d62.jpg

对比率代表着斜率的α,而亮度则是决定线性公式位移的情况,也就是β,Y=αX+β这个线性公式它所表达的情况如下
b5fbb739-ad16-4aea-bb50-deb328578278.jpg

α
值的范围落在0~255之间,而它的情况如下
d3e0387a-d9b9-48e4-af21-3c121584aaa0.jpg

再来下面是用伪码的方式表达亮度/对比的算法
305cc685-0886-4421-81fd-6761e4ef8e95.jpg

下面就是亮度/对比的程序了

亮度/对比实作
#include <cv.h>
#include <highgui.h>
#include <stdio.h>


int BrightnessPosition =
100;
int ContrastPosition =
100;

int HistogramBins =
64;
int HistogramBinWidth;
float HistogramRange1[
2]={0,256};
float *HistogramRange[
1]={&HistogramRange1[0]};

IplImage *Image1,*Image2;
CvHistogram *Histogram1;
IplImage *HistogramImage;

uchar LookupTableData[
256];
CvMat *LookupTableMatrix;
IplImage *LookupTableImage;
CvPoint Point1,Point2;


void OnTrackbar(int Position)
{
    int Brightness="BrightnessPosition-"
100;
    int Contrast="ContrastPosition" -
100;
    double Delta;
    double a,b;
    int y;

    
//Brightness/Contrast Formula
    if(Contrast>
0)
    {
        Delta=
127*Contrast/100;
        a=
255/(255-Delta*2);
        b=a*(Brightness-Delta);

        for(int x=
0;x<256;x++)
        {
            y=(int)(a*x+b);

            if(y<
0)
                y=
0;
            if(y>
255)
                y=
255;

            LookupTableData[x]=(uchar)y;
        }
    }
    else
    {
        Delta=-
128*Contrast/100;
        a=(
256-Delta*2)/255;
        b=a*Brightness+Delta;

        for(int x=
0;x<256;x++)
        {
            y=(int)(a*x+b);

            if(y<
0)
                y=
0;
            if(y>
255)
                y=
255;

            LookupTableData[x]=(uchar)y;
        }
    }
    
//End

    
//Look up table sketch
    cvSetZero(LookupTableImage);
    cvNot(LookupTableImage,LookupTableImage);
    Point2=cvPoint(
0,LookupTableData[0]);
    for(int i=
0;i<256;i++)
    {
        Point1=cvPoint(i,LookupTableData);
        cvLine(LookupTableImage,Point1,Point2,CV_RGB(
0,0,0),3);
        Point2=Point1;
    }
    cvLUT(Image1,Image2,LookupTableMatrix);
    
//End

    
//Gray Level Histogram
    cvCalcHist(
&Image2,Histogram1);
    cvNormalizeHist(Histogram1,
3000);

    cvSetZero(HistogramImage);
    cvNot(HistogramImage,HistogramImage);
    HistogramBinWidth = HistogramImage->width/HistogramBins;
    for(int i=
0;i<HistogramBins;i++)
    {
        Point1=cvPoint(i*HistogramBinWidth,
0);
        Point2=cvPoint((i+
1)*HistogramBinWidth,(int)cvQueryHistValue_1D(Histogram1,i));
        cvRectangle(HistogramImage,Point1,Point2,CV_RGB(
0,0,0),CV_FILLED);
    }
    
//End

    cvShowImage(
"Gray Level Histogram",HistogramImage);
    cvShowImage(
"Brightness/Contrast",Image2);
    cvShowImage(
"Image Enhance",LookupTableImage);
    cvZero(Image2);
}

int main()
{
    Image1=cvLoadImage(
"DarkClouds.jpg",0);
    Image2=cvCloneImage(Image1);

    Histogram1=cvCreateHist(
1,&HistogramBins,CV_HIST_ARRAY,HistogramRange);
    HistogramImage = cvCreateImage(cvSize(
320,200),8,1);

    LookupTableImage=cvCreateImage(cvSize(
256,256),8,3);
    LookupTableMatrix=cvCreateMatHeader(
1,256,CV_8UC1);
    cvSetData(LookupTableMatrix,LookupTableData,
0);

    LookupTableImage->origin=
1;
    HistogramImage->origin=
1;

    cvNamedWindow(
"Brightness/Contrast",1);
    cvNamedWindow(
"Gray Level Histogram",1);
    cvNamedWindow(
"Image Enhance",1);

    cvCreateTrackbar(
"brightness","Brightness/Contrast",&BrightnessPosition,200,OnTrackbar);
    cvCreateTrackbar(
"contrast","Brightness/Contrast",&ContrastPosition,200,OnTrackbar);

    OnTrackbar(
0);

    cvWaitKey(
0);
}

执行结果:
2f08ca14-d2bd-4db8-bdc1-e19f7c3720e3.jpg

这只程序同样也是用到CvHistogram数据结构,使用到两个拉轴(Trackbar),以及Look-up table的应用,//Brightness/Contrast Formula的批注内所包的就是亮度/对比算法伪码的实作,再来就是把它的线性系统化出来,也就是Y=αX+β的函数方程式,这个方程式,当然同等于Look up table,而之后,在把他们灰阶直方图的分布画出来,main()里面,当然是先读取目标图片转成灰阶,初始化绘制直方图与线性系统图片的空间,创立三个窗口接口,设立两个拉轴,并且将拉轴的事件函式设定成同一个的子程序的名称.而对于影像增强(Image Enhance)这个窗口接口,它所代表的含意如下

f76b72a4-2ab3-4257-a6db-716e21ebb746.jpg

X
轴代表为是原始灰阶的输入值,Y轴代表的是灰阶值所对应的结果,X轴跟Y轴的范围都是0~255,而这条直线公式也会受到斜率(α)以及平移(β)的结果改面灰阶值输入以及输出的对应,它是将一张原始灰阶图片的每一个像素值做线性函式的对应,使得每个灰阶值对应出来的结果产生了变化,由下面可以知道它(LUT)对应的关系

(a)
亮度条为0因此小于100的灰阶值都为0而灰阶值方图也像左偏移
bc6b544a-cb2c-421a-9083-cbe45aefa51b.jpg

(b)
亮度条为100,因此大于156的灰阶值都为255,而灰阶值方图也都向右偏移
d726b2c1-adad-4dd3-8d8c-896d5841d154.jpg

(c)
对比为0,这个时候斜率α0,因此输入的0~255的灰阶值输出都固定为128,因此整张图片都是灰阶值128的影像,而灰阶直方图则是所有数据都集中在128
cab7de49-316f-4862-af31-8b21098e3f4c.jpg

(d)
对比为100,这个时候斜率为255,而这样的图片又可以叫做二值化图片,因为输出结果非黑即白,而移动亮度则是在平移二值化的门坎值,由灰阶值方图可以得知,所有数据都被分开到0255两边
30a45260-02b2-4b00-8a53-8c5033040b85.jpg

上面所表达的其实就是一种Look-up table的表达方式,藉由一个输入灰阶值的矩阵,对应岀另一个不同的灰阶值数据,因此改变了原始灰阶值的数据,而整张图片也因此产生了变化
 


 

文章评论0条评论)

登录后参与讨论
我要评论
0
10
关闭 站长推荐上一条 /2 下一条