opencv----彩色图像对比度增强

图像对比度增强的方法可以分成两类:一类是直接对比度增强方法;另一类是间接对比度增强方法。

直方图拉伸和直方图均衡化是两种最常见的间接对比度增强方法。

直方图拉伸是通过对比度拉伸对直方图进行调整,从而“扩大”前景和背景灰度的差别,以达到增强对比度的目的,这种方法可以利用线性或非线性的方法来实现;

直方图均衡化则通过使用累积函数对灰度值进行“调整”以实现对比度的增强。

1.直方图拉伸

就是扩大将图像灰度的域值的一个过程,但是经常是基于灰度图像进行处理,以前在MATlab上对比度增强调用直方图函数就几行代码,但都是灰度图像上处理,需要在彩色图像进行处理,看别人的思想是从RGB-YUV-RGB的过程,在YUV空间增强再转回来,我跟着原理写代码,出了很多问题。详见http://blog.csdn.net/abcjennifer/article/details/7428737

/*
*@Function: Color image contrast enhancement
*@Date: 2012-4-5
*@Author: 张睿卿
*/

int ImageStretchByHistogram(IplImage *src1,IplImage *dst1)
/*************************************************
Function:      通过直方图变换进行图像增强,将图像灰度的域值拉伸到0-255
src1:               单通道灰度图像
dst1:              同样大小的单通道灰度图像
*************************************************/
{
    assert(src1->width==dst1->width);
    double p[256],p1[256],num[256];

    memset(p,0,sizeof(p));
    memset(p1,0,sizeof(p1));
    memset(num,0,sizeof(num));
    int height=src1->height;
    int width=src1->width;
    long wMulh = height * width;

    //statistics
    for(int x=0;x<src1->width;x++)
    {
        for(int y=0;y<src1-> height;y++){
            uchar v=((uchar*)(src1->imageData + src1->widthStep*y))[x];
            num[v]++;
        }
    }
    //calculate probability
    for(int i=0;i<256;i++)
    {
        p[i]=num[i]/wMulh;
    }

    //p1[i]=sum(p[j]);    j<=i;
    for(int i=0;i<256;i++)
    {
        for(int k=0;k<=i;k++)
            p1[i]+=p[k];
    }

    // histogram transformation
    for(int x=0;x<src1->width;x++)
    {
        for(int y=0;y<src1-> height;y++){
            uchar v=((uchar*)(src1->imageData + src1->widthStep*y))[x];
            ((uchar*)(dst1->imageData + dst1->widthStep*y))[x]= p1[v]*255+0.5;
        }
    }
    return 0;
}

void CCVMFCView::OnYcbcrY()
{
    IplImage* Y = cvCreateImage(cvGetSize(workImg),IPL_DEPTH_8U,1);
    IplImage* Cb= cvCreateImage(cvGetSize(workImg),IPL_DEPTH_8U,1);
    IplImage* Cr = cvCreateImage(cvGetSize(workImg),IPL_DEPTH_8U,1);
    IplImage* Compile_YCbCr= cvCreateImage(cvGetSize(workImg),IPL_DEPTH_8U,3);
    IplImage* dst1=cvCreateImage(cvGetSize(workImg),IPL_DEPTH_8U,3);

    int i;
    cvCvtColor(workImg,dst1,CV_BGR2YCrCb);
    cvSplit(dst1,Y,Cb,Cr,0);

     ImageStretchByHistogram(Y,dst1);

     for(int x=0;x<workImg->height;x++)
     {
         for(int y=0;y<workImg->width;y++)
         {
             CvMat* cur=cvCreateMat(3,1,CV_32F);
             cvmSet(cur,0,0,((uchar*)(dst1->imageData+x*dst1->widthStep))[y]);
             cvmSet(cur,1,0,((uchar*)(Cb->imageData+x*Cb->widthStep))[y]);
             cvmSet(cur,2,0,((uchar*)(Cr->imageData+x*Cr->widthStep))[y]);

             for(i=0;i<3;i++)
             {
                 double xx=cvmGet(cur,i,0);
                 ((uchar*)Compile_YCbCr->imageData+x*Compile_YCbCr->widthStep)[y*3+i]=xx;
             }
         }
     }

    cvCvtColor(Compile_YCbCr,workImg,CV_YCrCb2BGR);
     m_ImageType=3;
     Invalidate();
}

其中int ImageStretchByHistogram(IplImage *src1,IplImage *dst1)  是可以运行的,实现了灰度图像增强;

void CCVMFCView::OnYcbcrY()  我处理不好,只好呼唤睿卿 本人了。附上一个基于opencv已经实现灰度图像增强的代码.http://blog.csdn.net/zhaiwenjuan/article/details/6596011

#include "stdafx.h" 

#include "cv.h"
#include "highgui.h"
#include
#include
int ImageStretchByHistogram(IplImage *src,IplImage *dst); 

int _tmain(int argc, _TCHAR* argv[])
{
    IplImage * pImg;
    pImg=cvLoadImage("c:/lena.jpg",-1); 

//创建一个灰度图像
    IplImage* GrayImage = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
    IplImage* dstGrayImage = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
    cvCvtColor(pImg, GrayImage, CV_BGR2GRAY);
    ImageStretchByHistogram(GrayImage,dstGrayImage); 

  cvNamedWindow( "dstGrayImage", 1 ); //创建窗口
        cvNamedWindow( "GrayImage", 1 ); //创建窗口
        cvShowImage( "dstGrayImage", dstGrayImage ); //显示图像
        cvShowImage( "GrayImage", GrayImage ); //显示图像
        cvWaitKey(0); //等待按键 

  cvDestroyWindow( "dstGrayImage" );//销毁窗口
        cvDestroyWindow( "GrayImage" );//销毁窗口
        cvReleaseImage( &pImg ); //释放图像
        cvReleaseImage( &GrayImage ); //释放图像
        cvReleaseImage( &dstGrayImage ); //释放图像 

  return 0;
} 

int ImageStretchByHistogram(IplImage *src,IplImage *dst)
/*************************************************
  Function:
  Description:     因为摄像头图像质量差,需要根据直方图进行图像增强,
                   将图像灰度的域值拉伸到0-255
  Calls:
  Called By:
  Input:           单通道灰度图像
  Output:          同样大小的单通道灰度图像
  Return:
  Others:           http://www.xiaozhou.net/ReadNews.asp?NewsID=771
  DATE:               2007-1-5
*************************************************/
{
    //p[]存放图像各个灰度级的出现概率;
    //p1[]存放各个灰度级之前的概率和,用于直方图变换;
    //num[]存放图象各个灰度级出现的次数; 

    assert(src->width==dst->width);
    float p[256],p1[256],num[256];
    //清空三个数组
    memset(p,0,sizeof(p));
    memset(p1,0,sizeof(p1));
    memset(num,0,sizeof(num)); 

    int height=src->height;
    int width=src->width;
    long wMulh = height * width; 

    //求存放图象各个灰度级出现的次数
    // to do use openmp
    for(int x=0;x    {
        for(int y=0;y        {
            uchar v=((uchar*)(src->imageData + src->widthStep*y))[x];
            num[v]++;
        }
    } 

    //求存放图像各个灰度级的出现概率
    for(int i=0;i<256;i++)
    {
        p[i]=num[i]/wMulh;
    } 

    //求存放各个灰度级之前的概率和
    for(int i=0;i<256;i++)
    {
        for(int k=0;k<=i;k++)
            p1[i]+=p[k];
    } 

    //直方图变换
    // to do use openmp
    for(int x=0;x    {
        for(int y=0;y        {
            uchar v=((uchar*)(src->imageData + src->widthStep*y))[x];
            ((uchar*)(dst->imageData + dst->widthStep*y))[x]= p1[v]*255+0.5;
        }
    } 

    return 0; 

} 

2.既然直方图拉伸这条路走不通,只好试试,另一条,直方图均衡化了,还好我比较熟。

//图像增强- 彩色直方图均衡化
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include"opencv2/imgproc/imgproc.hpp"

using namespace std;
//彩色图像的直方图均衡化
IplImage* EqualizeHistColorImage(IplImage *pImage)
{
    IplImage *pEquaImage = cvCreateImage(cvGetSize(pImage), pImage->depth, 3);

    // 原图像分成各通道后再均衡化,最后合并即彩色图像的直方图均衡化
    const int MAX_CHANNEL = 4;
    IplImage *pImageChannel[MAX_CHANNEL] = {NULL};

    int i;
    for (i = 0; i < pImage->nChannels; i++)
        pImageChannel[i] = cvCreateImage(cvGetSize(pImage), pImage->depth, 1);

    cvSplit(pImage, pImageChannel[0], pImageChannel[1], pImageChannel[2], pImageChannel[3]);

    for (i = 0; i < pImage->nChannels; i++)
        cvEqualizeHist(pImageChannel[i], pImageChannel[i]);

    cvMerge(pImageChannel[0], pImageChannel[1], pImageChannel[2], pImageChannel[3], pEquaImage);

    for (i = 0; i < pImage->nChannels; i++)
        cvReleaseImage(&pImageChannel[i]);

    return pEquaImage;
}
int main( int argc, char** argv )
{
    const char *pstrWindowsSrcTitle = "原图";
    const char *pstrWindowsHisEquaTitle = "直方图均衡化后";

    // 从文件中加载原图
    IplImage *pSrcImage = cvLoadImage("lena.jpg", CV_LOAD_IMAGE_UNCHANGED);
    IplImage *pHisEquaImage = EqualizeHistColorImage(pSrcImage);

    cvNamedWindow(pstrWindowsSrcTitle, CV_WINDOW_AUTOSIZE);
    cvNamedWindow(pstrWindowsHisEquaTitle, CV_WINDOW_AUTOSIZE);
    cvShowImage(pstrWindowsSrcTitle, pSrcImage);
    cvShowImage(pstrWindowsHisEquaTitle, pHisEquaImage);

    cvWaitKey(0);

    cvDestroyWindow(pstrWindowsSrcTitle);
    cvDestroyWindow(pstrWindowsHisEquaTitle);
    cvReleaseImage(&pSrcImage);
    cvReleaseImage(&pHisEquaImage);
    return 0;
}

opencv----彩色图像对比度增强

时间: 2024-10-20 10:53:25

opencv----彩色图像对比度增强的相关文章

[blogs 算法原理 ]局部标准差实现对比度增强

基于“局部标准差”的图像增强(原理.算法.代码) 一.理论 图像增强算法的基本原则是“降低低频区域,突出高频区域”,以此强化边缘,达到增强的目的.最简单的例子就是通过原始图像减去高斯模糊处理后的图像,就能够将边缘强化出来. 直方图均衡化也是一种非常常见的增强方法.但是为了避免背景的干扰,更倾向于采用“局部”方法进行处理.我们这里着重研究自适应对比度增强(ACE)的相关内容. ACE的定义和原理(TODO) ACE算法的相关内容: 计算低频成分: 对于具体的像素,一般可以通过计算以该像素为中心的局

用于图像去雾的优化对比度增强算法

图像去雾哪家强?之前我们已经讨论过了著名的基于暗通道先验的图像去雾(Kaiming He, 2009)算法,如果你用兴趣可以参考: 暗通道优先的图像去雾算法(上) 暗通道优先的图像去雾算法(下) 此外,网上也有很多同道推荐了一篇由韩国学者所发表的研究论文<Optimized contrast enhancement for real-time image and video dehazing>(你也可以从文末参考文献[1]给出的链接中下载到这篇经典论文),其中原作者就提出了一个效果相当不错的图

优化的对比度增强算法用于有雾图像的清晰化处理(算法效果是我目前看到最为稳定的,且对天空具有天然的免疫力,极力推荐有需要的朋友研究)。

在未谈及具体的算法流程前,先贴几幅用该算法处理的效果. 不知道各位对这个算法的效果第一印象如何. 这个算法的原理来自于文章<Optimized contrast enhancement for real-time image and video dehazing>,作者是韩国人. 这个算法也是基于大气散射模型: 和现在一些常见的去雾文章有明显的不同的是,这篇文章的并不是基于暗通道原理的,也不是把重点强调在透射率图的细化上,而是提出了一种新的得到粗透射率图的方法.并且文章分别讲到了静态图像和视频

Opencv——彩色图像灰度化的三种算法

为了加快处理速度在图像处理算法中,往往需要把彩色图像转换为灰度图像.24为彩色图像每个像素用3个字节表示,每个字节对应着RGB分量的亮度. 当RGB分量值不同时,表现为彩色图像:当RGB分量相同时,变现为灰度图像: 一般来说,转换公式有3中. (1)Gray(i,j)=[R(i,j)+G(i,j)+B(i,j)]/3; (2)Gray(i,j)=0.299*R(i,j)+0.587*G(i,j)+0.144*B(i,j); (3)Gray(i,j)=G(i,j);//从2可以看出G的分量比较大所

利用图像的直方图进行对比度增强的方法

一般情况下,二值图像的灰度值等级是21 =2(0\1),灰度图像的灰度值等级是28=256(0-255), 对于灰度图像来说,灰度值集中在较低的级别时,图像较暗,反之,则较亮,且灰度值分布较均匀时,图像的对比度也会比较明显. 1.图像直方图的计算方法 对于灰度图像,图像的灰度值等级为256,将从0到255的每一个灰度等级对应在图像中的像素点的个数统计出来,然后,通过计算统计个数与整幅图像对应像素点的总个数的比值得到每一个灰度值等级在图像中出现的概率密度值,将灰度等级作为自变量,在图像中出现的概率

Opencv——彩色图像转成灰度图像

// PS_Algorithm.h #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include <iostream> #include <string> #include "cv.h" #include "highgui.h" #include "cxmat.hpp" #include "cxcore.hpp" usi

opencv之对比度和亮度的调节

opencv之对比度和亮度的调节 公式 \[ g(x) = a*f(x) + b\] 注:\(f(x)\) 为输入图像, \(g(x)\) 为输出图像. 注:\(a\)为增益,用于控制图像的对比度: \(b\)为偏置,用于控制图像的亮度. 代码 for (int y = 0; y < image.rows; ++y) { for (int x = 0; x < image.cols; ++x) { for (int c = 0; c < image.channel; ++c) { new

对比度增强

函数imadjust将图像I中的亮度值映射到J中的新值 J = imadjust(I,[low_in; high_in],[low_out; high_out])    二维图调用格式,三维图同理 low_in 以下的值映射到 low_out,high_in 以上的值映射到high_out. [low_out; high_out],默认值是[0 1] close all;clear;clc; load wbarb; rgb=ind2rgb(X,map); gray=ind2gray(X,map)

opencv 图像对比度亮度调整

#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include "opencv2/imgproc/imgproc.hpp" #include <iostream> using namespace std; using namespace cv; int g_nContrastValue; //对比度值 int g_nBrightValue; //亮度值