精华内容
下载资源
问答
  • OpenCV 局部自适应对比度增强ACE算法

    千次阅读 2019-05-07 14:53:38
    图像的对比度增强算法在很多场合都有着重要的应用,特别是在医学图像上,这是因为在众多疾病的诊断中,医学图像的视觉检查时很有必要的。而医学图像由于本身及成像条件的限制,图像的对比度很低。因此,在这个方面...

    图像的对比度增强算法在很多场合都有着重要的应用,特别是在医学图像上,这是因为在众多疾病的诊断中,医学图像的视觉检查时很有必要的。而医学图像由于本身及成像条件的限制,图像的对比度很低。因此,在这个方面已经开展了很多的研究。这种增强算法一般都遵循一定的视觉原则。众所周知,人眼对高频信号(边缘处等)比较敏感。虽然细节信息往往是高频信号,但是他们时常嵌入在大量的低频背景信号中,从而使得其视觉可见性降低。因此适当的提高高频部分能够提高视觉效果并有利于诊断。

         在这一方面,传统的线性对比度拉升以及直方图均衡化是使用的最为广泛的全局图像增强方法。对比度拉升线性的调整了图像的动态范围,而直方图均衡化栖利用累计直方图分布概率重新映射图像的数据。这些方法虽然简单,但是都没有考虑到局部的信息。并且,全局直方图均衡化(GHE)还会产生使得一些噪音过度加强。

         在局部对比度增强方面,有两种方式是最为有名的,一种是自适应直方图均衡化(AHE),这个算法可以参考我的博文https://blog.csdn.net/cyf15238622067/article/details/89202361

    https://blog.csdn.net/cyf15238622067/article/details/87798128

    还有一种就是自适应对比度增强(ACE)。AHE算法使用局部的直方图的相关信息对数据进行映射。这改变了图像的对比度,但是需要大量的计算。后来有人利用了双线性差值技术克服了这个问题,首先将图像分块,然后分别计算这些快内部的映射关系。为了增强某一个像素点的值,映射关系通过与这个像素所在块相邻的四个块的映射关系差值获得。在这个算法中,仅仅需要一个块大小的参数(在我的博文中还对参数进行了扩展)。

          ACE算法采用了反锐化掩模技术,我们对此过程解释如下:首先图像被分成两个部分。一是低频的反锐化掩模(unsharp mask)部分,可以通过图像的低通滤波(平滑,模糊技术)获得。二是高频成分,可以过原图减去反锐化掩模获取。然后高频部分被放大(放大系数即为对比度增益CG)并加入到反锐化掩模中去,最后得到增强的图像。ACE算法的核心就是如何计算CG,这里将介绍两种简单的CG计算方法。

    自适应对比度增强

    在图像处理的方法中,自适应方法是与图像本身信息相关,根据图像对图特征对图像进行处理的一系列方法,这些方法往往具有更好的鲁棒性、普适性。而本文中提到的这种ACE方法由NarendraPM Narendra P MNarendraPM等人在《Real-Time Adaptive Contrast Enhancement》中提到,原理简单易懂,有兴趣的朋友可以点击链接去阅读。https://ieeexplore.ieee.org/abstract/document/4767166

    对于图像中的每一个点,分别计算其局部均值与局部标准差;

            上述式子中,f(s,k) 代表坐标为(s,k) 的点的像素值,M(i,j) 为以点(i,j)为中心,窗口大小为[(2n+1),(2m+1)] [(2n+1),(2m+1)][(2n+1),(2m+1)]的区域的局部均值,对应的σ2(i,j) \sigma ^{2}(i,j)σ2(i,j)为局部的方差,σ(i,j) \sigma (i,j)σ(i,j)为局部图像的标准差。
           在求得局部均值与标准差后,就可以对图像进行增强了,具体的公式如下;

                                                        

    再来分析一下,上面式子的含义;如果将每个点的局部均值M(i,j) M(i,j)M(i,j)构成一张图,其实就是均值滤波的结果,而在《数字图像傅里叶变换的物理意义及简单应用》中,我提到过均值滤波是一种低通滤波,获得的是图像的低频部分,也就是背景部分,f(i,j)−M(i,j) f(i,j)-M(i,j)f(i,j)−M(i,j)就可以用来量化图像中的一个点是高频还是低频。而在一般情况下,G GG 都是大于1的,所以通过 G(f(i,j)−M(i,j)) G(f(i,j)-M(i,j))G(f(i,j)−M(i,j))可以实现对图像的高频部分的放大,进而对图像进行增强。
                                        

    再来看看参数G GG,经过上面的过程可以看出,如果G GG 是一个固定参数,比如都取5,通过式子中的局部均值,我们已经能够将图像实现一定程度上的自适应增强了。那么为什么还要在参数G中引入标准差呢?

    我们回忆一下对比度增强的初衷,对比度增强是为了让本身对比度不强的图像的对比度变得明显,而对本身对比度很强的图像,是没必要做增强的。那么在同一图像中,我们尤其需要增强对比度不强的部分。而方差表示的是图像的像素值的均匀性,我们可以认为方差越大的局部区域,其像素值越不均匀,对比度越强;反之,方差越小的局部区域,其像素值越均匀,对比度越弱。因此,在参数G GG中除以了局部标准差,可以让图像中对比度较弱的部分的增强效果更加明显。

           其次,如果对整张图像中所有点进行等比例增强,图像中本身就是高频的部分出现过增强的现象,图像看起来十分奇怪。
     

    彩色图像的ACE

    在网上看到有人说,对彩色图像增强可以分别对RGB三通道进行增强后进行合并。这个观点是错误的,因为分别对各个通道进行增强,会引起图像色相的变化,图像会变的不是其原来的颜色了。

    所以需要将图像转到HSI色彩空间,或者是YCrCb颜色空间。前者只需要对I亮度通道进行增强,而H、S分别代表的色调和饱和度通道不需要变化。后者用Y通道表示亮度,只需要对Y通道进行增强即可。增强之后再合并通道,转换回RGB空间便完成了对彩色图像的增强。
     

    代码实现:

    #include<opencv2/opencv.hpp>
    #include<vector>
    #include<iostream>
    
    using namespace std;
    using namespace cv;
    
    
    //--------------------
    //函数功能:获取图像的局部均值与局部标准差的图
    //函数名称:getVarianceMean
    //函数参数:Mat &scr:输入图像,为单通道;
    //函数参数:Mat &meansDst:计算得到的均值的图,均值的值与输入图像中的点一一对应,为单通道;
    //函数参数:Mat &varianceDst:计算得到的标准差的图,标准差的值与输入图像中的点一一对应,为单通道;
    //函数参数:int winSize:局部均值的窗口大小,应为单数;
    //返回类型:bool
    //--------------------
    
    bool getVarianceMean(Mat &scr, Mat &meansDst, Mat &varianceDst, int winSize)
    {
        if (!scr.data)  //判断图像是否被正确读取;
        {
            cerr << "获取方差与均值的函数读入图片有误";
            return false;
        }
    
        if (winSize % 2 == 0)
        {
            cerr << "计算局部均值与标准差的窗口大小应该为单数";
            return false;
        }
    
        Mat copyBorder_yChannels;                        //扩充图像边界;
        int copyBorderSize = (winSize - 1) / 2;
        copyMakeBorder(scr, copyBorder_yChannels, copyBorderSize, copyBorderSize, copyBorderSize, copyBorderSize, BORDER_REFLECT);
    
        for (int i = (winSize - 1) / 2; i < copyBorder_yChannels.rows - (winSize - 1) / 2; i++)
        {
            for (int j = (winSize - 1) / 2; j < copyBorder_yChannels.cols - (winSize - 1) / 2; j++)
            {
                
                Mat temp = copyBorder_yChannels(Rect(j - (winSize - 1) / 2, i - (winSize - 1) / 2, winSize, winSize));   //截取扩展后的图像中的一个方块;
    
                Scalar  mean;
                Scalar  dev;
                meanStdDev(temp, mean, dev);
                
                varianceDst.at<float>(i - (winSize - 1) / 2, j - (winSize - 1) / 2) = dev.val[0];     ///一一对应赋值;
                meansDst.at<float>(i - (winSize - 1) / 2, j - (winSize - 1) / 2) = mean.val[0];
            }
        }
    
        
        return true;
    }
    
    //--------------------------
    //函数功能:获取图像的局部均值与局部标准差的图
    //函数名称:adaptContrastEnhancement
    //函数参数:Mat &scr:输入图像,为三通道RGB图像;
    //函数参数:Mat &dst:增强后的输出图像,为三通道RGB图像;
    //函数参数:int winSize:局部均值的窗口大小,应为单数;
    //函数参数:int maxCg:增强幅度的上限;
    //返回类型:bool
    //--------------------
    
    bool adaptContrastEnhancement(Mat &scr, Mat &dst, int winSize,int maxCg)
    {
        if (!scr.data)  //判断图像是否被正确读取;
        {
            cerr << "自适应对比度增强函数读入图片有误";
            return false;
        }
    
        Mat ycc;                        //转换空间到YCrCb;
        cvtColor(scr, ycc, COLOR_RGB2YCrCb);
    
        vector<Mat> channels(3);        //分离通道;
        split(ycc, channels);
    
        
        Mat localMeansMatrix(scr.rows , scr.cols , CV_32FC1);
        Mat localVarianceMatrix(scr.rows , scr.cols , CV_32FC1);
        
        if (!getVarianceMean(channels[0], localMeansMatrix, localVarianceMatrix, winSize))   //对Y通道进行增强;
        {
            cerr << "计算图像均值与标准差过程中发生错误";
            return false;
        }
    
        Mat temp = channels[0].clone();
    
        Scalar  mean;
        Scalar  dev;
        meanStdDev(temp, mean, dev);
    
        float meansGlobal = mean.val[0];
        Mat enhanceMatrix(scr.rows, scr.cols, CV_8UC1);
    
        for (int i = 0; i < scr.rows; i++)            //遍历,对每个点进行自适应调节
        {
            for (int j = 0; j < scr.cols; j++)
            {
                if (localVarianceMatrix.at<float>(i, j) >= 0.01)
                {
                    float cg = 0.2*meansGlobal / localVarianceMatrix.at<float>(i, j);
                    float cgs = cg > maxCg ? maxCg : cg;
                    cgs = cgs < 1 ? 1 : cgs;
                    
                    int e = localMeansMatrix.at<float>(i, j) + cgs* (temp.at<uchar>(i, j) - localMeansMatrix.at<float>(i, j));
                    if (e > 255){ e = 255; }
                    else if (e < 0){ e = 0; }
                    enhanceMatrix.at<uchar>(i, j) = e;
                }
                else
                {
                    enhanceMatrix.at<uchar>(i, j) = temp.at<uchar>(i, j);
                }
            }
                
        }
        
        channels[0] = enhanceMatrix;    //合并通道,转换颜色空间回到RGB
        merge(channels, ycc);
    
        cvtColor(ycc, dst, COLOR_YCrCb2RGB);
            
    }
    
    //----------------
    //主函数
    //----------------
    void main()
    {
        Mat scr = imread("temp1.jpg", IMREAD_COLOR);  //以彩色的方式读入图像
             
        if (!scr.data)               //判断图像是否被正确读取;
        {
            return;
        }
    
        const int WINSIZE = 15;      //WINSIZE表示求均值与方差的窗口大小,应该是单数
        const int MAXCG = 10;        //设定最大的增强比例
    
        Mat dst = scr.clone();
    
        adaptContrastEnhancement(scr, dst, WINSIZE,MAXCG);
        
        imwrite("01.png", dst);      //写出图像
        
        return;
    }

    效果图:


    ---------------------
    作者:Dwyane05
    来源:CSDN
    原文:https://blog.csdn.net/cyf15238622067/article/details/89202725
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • 图像的对比度增强算法在很多场合都有着重要的应用,特别是在医学图像上,这是因为在众多疾病的诊断中,医学图像的视觉检查时很有必要的。而医学图像由于本身及成像条件的限制,图像的对比度很低。因此,在这个方面...

     

    图像的对比度增强算法在很多场合都有着重要的应用,特别是在医学图像上,这是因为在众多疾病的诊断中,医学图像的视觉检查时很有必要的。而医学图像由于本身及成像条件的限制,图像的对比度很低。因此,在这个方面已经开展了很多的研究。这种增强算法一般都遵循一定的视觉原则。众所周知,人眼对高频信号(边缘处等)比较敏感。虽然细节信息往往是高频信号,但是他们时常嵌入在大量的低频背景信号中,从而使得其视觉可见性降低。因此适当的提高高频部分能够提高视觉效果并有利于诊断。

         在这一方面,传统的线性对比度拉升以及直方图均衡化是使用的最为广泛的全局图像增强方法。对比度拉升线性的调整了图像的动态范围,而直方图均衡化栖利用累计直方图分布概率重新映射图像的数据。这些方法虽然简单,但是都没有考虑到局部的信息。并且,全局直方图均衡化(GHE)还会产生使得一些噪音过度加强。

         在局部对比度增强方面,有两种方式是最为有名的,一种是自适应直方图均衡化(AHE),这个算法可以参考我的博文https://blog.csdn.net/cyf15238622067/article/details/89202361

    https://blog.csdn.net/cyf15238622067/article/details/87798128

    还有一种就是自适应对比度增强(ACE)。AHE算法使用局部的直方图的相关信息对数据进行映射。这改变了图像的对比度,但是需要大量的计算。后来有人利用了双线性差值技术克服了这个问题,首先将图像分块,然后分别计算这些快内部的映射关系。为了增强某一个像素点的值,映射关系通过与这个像素所在块相邻的四个块的映射关系差值获得。在这个算法中,仅仅需要一个块大小的参数(在我的博文中还对参数进行了扩展)。

          ACE算法采用了反锐化掩模技术,我们对此过程解释如下:首先图像被分成两个部分。一是低频的反锐化掩模(unsharp mask)部分,可以通过图像的低通滤波(平滑,模糊技术)获得。二是高频成分,可以过原图减去反锐化掩模获取。然后高频部分被放大(放大系数即为对比度增益CG)并加入到反锐化掩模中去,最后得到增强的图像。ACE算法的核心就是如何计算CG,这里将介绍两种简单的CG计算方法。

    自适应对比度增强  

    在图像处理的方法中,自适应方法是与图像本身信息相关,根据图像对图特征对图像进行处理的一系列方法,这些方法往往具有更好的鲁棒性、普适性。而本文中提到的这种ACE方法由NarendraPM Narendra P MNarendraPM等人在《Real-Time Adaptive Contrast Enhancement》中提到,原理简单易懂,有兴趣的朋友可以点击链接去阅读。https://ieeexplore.ieee.org/abstract/document/4767166

       对于图像中的每一个点,分别计算其局部均值与局部标准差;
                                          

      上述式子中,f(s,k) f(s,k)f(s,k)代表坐标为(s,k) (s,k)(s,k)的点的像素值,M(i,j) M(i,j)M(i,j)为以点(i,j) (i,j)(i,j)为中心,窗口大小为[(2n+1),(2m+1)] [(2n+1),(2m+1)][(2n+1),(2m+1)]的区域的局部均值,对应的σ2(i,j) \sigma ^{2}(i,j)σ2(i,j)为局部的方差,σ(i,j) \sigma (i,j)σ(i,j)为局部图像的标准差。
      
      在求得局部均值与标准差后,就可以对图像进行增强了,具体的公式如下;

                                                    

      上式中,I(i,j) I(i,j)I(i,j)为增强后的像素值,M MM为全局均值(你也可以把它设为某一合理数值),α \alphaα是一个系数参数,一般取小于1大于0的小数。

      再来分析一下,上面式子的含义;如果将每个点的局部均值M(i,j) M(i,j)M(i,j)构成一张图,其实就是均值滤波的结果,而在《数字图像傅里叶变换的物理意义及简单应用》中,我提到过均值滤波是一种低通滤波,获得的是图像的低频部分,也就是背景部分,f(i,j)−M(i,j) f(i,j)-M(i,j)f(i,j)−M(i,j)就可以用来量化图像中的一个点是高频还是低频。而在一般情况下,G GG 都是大于1的,所以通过 G(f(i,j)−M(i,j)) G(f(i,j)-M(i,j))G(f(i,j)−M(i,j))可以实现对图像的高频部分的放大,进而对图像进行增强。

                                                        

      再来看看参数G GG,经过上面的过程可以看出,如果G GG 是一个固定参数,比如都取5,通过式子中的局部均值,我们已经能够将图像实现一定程度上的自适应增强了。那么为什么还要在参数G中引入标准差呢?

      我们回忆一下对比度增强的初衷,对比度增强是为了让本身对比度不强的图像的对比度变得明显,而对本身对比度很强的图像,是没必要做增强的。那么在同一图像中,我们尤其需要增强对比度不强的部分。而方差表示的是图像的像素值的均匀性,我们可以认为方差越大的局部区域,其像素值越不均匀,对比度越强;反之,方差越小的局部区域,其像素值越均匀,对比度越弱。因此,在参数G GG中除以了局部标准差,可以让图像中对比度较弱的部分的增强效果更加明显。

      其次,如果对整张图像中所有点进行等比例增强,图像中本身就是高频的部分出现过增强的现象,图像看起来十分奇怪。

    彩色图像的ACE

    在网上看到有人说,对彩色图像增强可以分别对RGB三通道进行增强后进行合并。这个观点是错误的,因为分别对各个通道进行增强,会引起图像色相的变化,图像会变的不是其原来的颜色了。

      所以需要将图像转到HSI色彩空间,或者是YCrCb颜色空间。前者只需要对I亮度通道进行增强,而H、S分别代表的色调和饱和度通道不需要变化。后者用Y通道表示亮度,只需要对Y通道进行增强即可。增强之后再合并通道,转换回RGB空间便完成了对彩色图像的增强。
     

    代码实现:


    #include<opencv2/opencv.hpp>
    #include<vector>
    #include<iostream>

    using namespace std;
    using namespace cv;


    //--------------------
    //函数功能:获取图像的局部均值与局部标准差的图
    //函数名称:getVarianceMean
    //函数参数:Mat &scr:输入图像,为单通道;
    //函数参数:Mat &meansDst:计算得到的均值的图,均值的值与输入图像中的点一一对应,为单通道;
    //函数参数:Mat &varianceDst:计算得到的标准差的图,标准差的值与输入图像中的点一一对应,为单通道;
    //函数参数:int winSize:局部均值的窗口大小,应为单数;
    //返回类型:bool
    //--------------------

    bool getVarianceMean(Mat &scr, Mat &meansDst, Mat &varianceDst, int winSize)
    {
        if (!scr.data)  //判断图像是否被正确读取;
        {
            cerr << "获取方差与均值的函数读入图片有误";
            return false;
        }

        if (winSize % 2 == 0)
        {
            cerr << "计算局部均值与标准差的窗口大小应该为单数";
            return false;
        }

        Mat copyBorder_yChannels;                        //扩充图像边界;
        int copyBorderSize = (winSize - 1) / 2;
        copyMakeBorder(scr, copyBorder_yChannels, copyBorderSize, copyBorderSize, copyBorderSize, copyBorderSize, BORDER_REFLECT);

        for (int i = (winSize - 1) / 2; i < copyBorder_yChannels.rows - (winSize - 1) / 2; i++)
        {
            for (int j = (winSize - 1) / 2; j < copyBorder_yChannels.cols - (winSize - 1) / 2; j++)
            {
                
                Mat temp = copyBorder_yChannels(Rect(j - (winSize - 1) / 2, i - (winSize - 1) / 2, winSize, winSize));   //截取扩展后的图像中的一个方块;

                Scalar  mean;
                Scalar  dev;
                meanStdDev(temp, mean, dev);
                
                varianceDst.at<float>(i - (winSize - 1) / 2, j - (winSize - 1) / 2) = dev.val[0];     ///一一对应赋值;
                meansDst.at<float>(i - (winSize - 1) / 2, j - (winSize - 1) / 2) = mean.val[0];
            }
        }

        
        return true;
    }

    //--------------------------
    //函数功能:获取图像的局部均值与局部标准差的图
    //函数名称:adaptContrastEnhancement
    //函数参数:Mat &scr:输入图像,为三通道RGB图像;
    //函数参数:Mat &dst:增强后的输出图像,为三通道RGB图像;
    //函数参数:int winSize:局部均值的窗口大小,应为单数;
    //函数参数:int maxCg:增强幅度的上限;
    //返回类型:bool
    //--------------------

    bool adaptContrastEnhancement(Mat &scr, Mat &dst, int winSize,int maxCg)
    {
        if (!scr.data)  //判断图像是否被正确读取;
        {
            cerr << "自适应对比度增强函数读入图片有误";
            return false;
        }

        Mat ycc;                        //转换空间到YCrCb;
        cvtColor(scr, ycc, COLOR_RGB2YCrCb);

        vector<Mat> channels(3);        //分离通道;
        split(ycc, channels);

        
        Mat localMeansMatrix(scr.rows , scr.cols , CV_32FC1);
        Mat localVarianceMatrix(scr.rows , scr.cols , CV_32FC1);
        
        if (!getVarianceMean(channels[0], localMeansMatrix, localVarianceMatrix, winSize))   //对Y通道进行增强;
        {
            cerr << "计算图像均值与标准差过程中发生错误";
            return false;
        }

        Mat temp = channels[0].clone();

        Scalar  mean;
        Scalar  dev;
        meanStdDev(temp, mean, dev);

        float meansGlobal = mean.val[0];
        Mat enhanceMatrix(scr.rows, scr.cols, CV_8UC1);

        for (int i = 0; i < scr.rows; i++)            //遍历,对每个点进行自适应调节
        {
            for (int j = 0; j < scr.cols; j++)
            {
                if (localVarianceMatrix.at<float>(i, j) >= 0.01)
                {
                    float cg = 0.2*meansGlobal / localVarianceMatrix.at<float>(i, j);
                    float cgs = cg > maxCg ? maxCg : cg;
                    cgs = cgs < 1 ? 1 : cgs;
                    
                    int e = localMeansMatrix.at<float>(i, j) + cgs* (temp.at<uchar>(i, j) - localMeansMatrix.at<float>(i, j));
                    if (e > 255){ e = 255; }
                    else if (e < 0){ e = 0; }
                    enhanceMatrix.at<uchar>(i, j) = e;
                }
                else
                {
                    enhanceMatrix.at<uchar>(i, j) = temp.at<uchar>(i, j);
                }
            }
                
        }
        
        channels[0] = enhanceMatrix;    //合并通道,转换颜色空间回到RGB
        merge(channels, ycc);

        cvtColor(ycc, dst, COLOR_YCrCb2RGB);
            
    }

    //----------------
    //主函数
    //----------------
    void main()
    {
        Mat scr = imread("temp1.jpg", IMREAD_COLOR);  //以彩色的方式读入图像
             
        if (!scr.data)               //判断图像是否被正确读取;
        {
            return;
        }

        const int WINSIZE = 15;      //WINSIZE表示求均值与方差的窗口大小,应该是单数
        const int MAXCG = 10;        //设定最大的增强比例

        Mat dst = scr.clone();

        adaptContrastEnhancement(scr, dst, WINSIZE,MAXCG);
        
        imwrite("01.png", dst);      //写出图像
        
        return;
    }

     

    效果图

     

    参考
    Narendra P M, Fitch R C. Real-time adaptive contrast enhancement[J]. IEEE transactions on pattern analysis and machine intelligence, 1981 (6): 655-661.
    http://www.cnblogs.com/Imageshop/p/3324282.html
    https://blog.csdn.net/u013921430/article/details/83865427 
     

    展开全文
  • OpenCV是跨平台的强大的计算机视觉识别和图像处理的开源库,可以利用他来实现:模式识别、构建神经网络、深度学习,总之用途多多,入门级就先做一下图像处理吧! 基本的图像处理算法(图像灰阶化、二值化、仿射变换...

    http://www.cnblogs.com/wonderchief/p/6656915.html

    OpenCV是跨平台的强大的计算机视觉识别和图像处理的开源库,可以利用他来实现:模式识别、构建神经网络、深度学习,总之用途多多,入门级就先做一下图像处理吧!

    基本的图像处理算法(图像灰阶化、二值化、仿射变换、缩放变换以及各种插值方法)在百度或者谷歌上就能随便找到算法,但是我想找到一种可以进行局部球状或者弧形状梯级式变形,找了很久没有,嗯。。。。关键问题还是得靠自己

    问题分析:

    如果我要实现想现实中如下的变形,应该怎么办?(本人文化很低,不懂得这种叫什么现象,暂且叫:弧形变形吧)

    嗯,通过观察一下,这个形状有点像2次函数,也像sin函数,经过对比,还是sin会接近一些

    于是打开octive手动画一下:

    通过观察可知,调整sin函数的系数可以调整震幅,那么,我们假设:

    v(i,j)是矩阵任意一点

    v(i,j)=v(i - sin(j/H/PI),j)进行变换

    那么就可以对图像进行sin函数扭曲

     

    如果要实现可变振幅,还要进一步处理:

    v(i,j)=v(i - (i/W)*sin(j/H/PI),j)

     

    如果要实现四边都是完美过度,还要进行调整:

    具体代码如下:

    复制代码
    //image longitudinal warping changeable amplitudes
    int xWarp(cv::Mat mat, int dst)
    {
        int w = mat.cols;
        int h = mat.rows;
        cv::Mat t = mat.clone();
        //cols
        for (int i = 0; i < w; i++)
        {
            //rows
            for (int j = 0; j < h; j++)
            {
                double delta;
                if (i < (w / 2))
                    delta = (double)i / (double)w * dst * sin(((double)j / (double)h) * pi);
                else
                    delta = (1 - (double)i / (double)w) * dst * sin(((double)j / (double)h) * pi);
                mat.at(j, i) = t.at(j, i - delta);
            }
        }
        return 0;
    }
    复制代码

    转载于:https://www.cnblogs.com/jukan/p/7444790.html

    展开全文
  • OpenCV——对比度增强

    万次阅读 2019-06-15 14:41:59
    尽管我们通过各种方法来采集高质量的图像,...对比度增强的几种常用的方法:线性变换、分段线性变换、伽马变换、直方图正规化、直方图均衡化、局部自适应直方图均衡化; 这些方法计算代价小,但是却产生了较为理想...

    尽管我们通过各种方法来采集高质量的图像,但是有的时候还是不够好,需要通过图像增强技术提高其质量。

    图像增强技术:主要解决由于图像的灰度级范围较小造成的对比度较低的问题,目的就是将输出图像的灰度值放大到指定的程度,使得图像看起来更加清晰。

    对比度增强的几种常用的方法:线性变换、分段线性变换、伽马变换、直方图正规化、直方图均衡化、局部自适应直方图均衡化;

    这些方法计算代价小,但是却产生了较为理想的效果

    4.1 灰度直方图

    灰度直方图是图像灰度级的函数,用来描述每个灰度级在图像矩阵中的像素个数或者占有率。即,统计0~255之间每个灰度级对应的像素个数。图像对比度通过灰度级范围来度量,灰度级范围越大代表对比度越高;反之,对比度越低的图像在视觉上给人的感觉是看起来不够清晰。Matplotlib提供计算直方图的函数hist。

    4.2 线性变换

    O(r, c)=a * I(r, c)+b, 0 \leqslant r<H, 0 \leqslant c<W

    如果a>1,则输出图像O的对比度比I 有所增大;如果0<a<1,则O的对比度比I 有所减小。而b值的改变,影响 的是输出图像的亮度,当b>0时,亮度增加;当b<0时,亮度减小。

    线性变换计算出的输出值可能要大于255,需要将这些值截断为255,而不是取模运算;

    4.3 分段线性变换

    上述线性变换是对整个灰度级范围使用了相同的参数,有的时候也需要针对不同的灰度级范围进行不同的线性变换;

    分段线性变换:经常用于降低较亮或较暗区域的对比度来增强灰度级处于中间范围的对比度,或者压低中间范围的对比度来增强较亮或较暗区域的对比度。

    O(r, c)=\left\{\begin{array}{ll}{0.5 * I(r, c),} & {I(r, c)<50} \\ {3.6 * I(r, c)-310,} & {50 \leqslant I(r, c)<150} \\ {0.238 * I(r, c)+194,} & {150 \leqslant I(r, c) \leqslant 255}\end{array}\right.

    4.4 直方图正规化

    可以看出,上述两种线性变换的参数需要根据不同的应用及图像自身的信息进行合理的选择,可以需要进行多次的测试,所以选择合适的参数是相当的麻烦。

    自动选择a 和 b 的方法:直方图正规化

    a=\frac{O_{\max }-O_{\min }}{I_{\max }-I_{\min }}   ,b=O_{\min }-\frac{O_{\max }-O_{\min }}{I_{\max }-I_{\min }} * I_{\min }, 即图像 I 到 图像 O 的灰度级范围的映射

    \boldsymbol{O}(r, c)=\frac{\boldsymbol{O}_{\max }-\boldsymbol{O}_{\min }}{I_{\max }-\boldsymbol{I}_{\min }}\left(\boldsymbol{I}(r, c)-\boldsymbol{I}_{\min }\right)+\boldsymbol{O}_{\min }

    函数minMaxLoc函数不仅可以计算出矩阵的最大值和最小值,还可以求出最大值最小值的位置。

    正规化函数 normalize

    OpenCV中提供函数

    void normalize(InputArray src, OutputArray dst, doubel alpha = , double beta = 0, int norm_tyoe=NORM_L2, int dtype = -1, InputArray mask = noArray())

    norm_type:

    norm_ty pe=NORM_L1:        1-范数——计算矩阵中值的绝对值的和

    norm_ty pe=NORM_L2         2-范数——计算矩阵中值的平方和的开方

    norm_type=NORM_INF        ∞-范数——计算矩阵中值的绝对值的最大值

    norm_type=NORM_MINMAX   计算src的最小值srcminsrc的最大值 srcmax

    注意,使用normalize可以处理多通道矩阵,分别对每一个通道进行正规化操作。

    4.5 增强图像对比度的非线性变换——伽马变换

    伽马变换就是令\mathrm{O}(\mathrm{r}, \mathrm{c})=\mathrm{I}(\mathrm{r}, \mathrm{c}) ^\gamma0≤r<H0≤c<W

    在对图像进行伽马变换时,应先将图像的灰度值归一化到[01]范围,然后再进行幂运算。如果原矩阵是CV_8U类型的,那么在进行幂运算时,大于255的值会自动截断为255

    4.6 全局直方图均衡化

    伽马变换在提升对比度上有比较好的效果,但是需要手动调节γ值。下面介绍一种利用图像的直方图自动调节图像对比度的方法。

    全局直方图均衡化操作是对图像I 进行改变,使得输出图像O的灰度直方图hist O 的,即每一个灰度级的像素点个数是“几乎的。即\mathrm{O} (\mathrm{k})\approx\frac{H * W}{256}

    \sum_{k=0}^{p} \operatorname{hist}_{I}(k)=\sum_{k=0}^{q} \operatorname{hist}_{O}(k),其中\sum_{k=0}^{p} \operatorname{hist}_{I}(k)\sum_{k=0}^{q} \text { hist }_{O}(q)称为 I O累加直方图。

    从亮度级为p的输入像素到亮度级为q的输出像素的映射\boldsymbol{O}(r, c)=\frac{\sum_{k=0}^{I(r, c)} \mathrm{hist}_{I}(k)}{H * W} * 256-1

    直方图均衡化在提升图像对比度上有显著的效果。但是直方图均衡化的结果  容易受噪声、阴影和光照变换的影响。

    4.7 限制对比度的自适应直方图均衡化

    自适应直方图均衡化首先将图像划分为不重叠的区域块,然后对每一个块分别进行直方图均衡化。

    显然,在没有噪声影响的情况下,每一个小区域的灰度直方图会被限制在一个小的灰度级范围内,但是如果有噪声,每一个分割的区域块执行直方图均衡化后,噪声会被放大。

    限制对比度:如果直方图的bin 超过了提前预设的限制对比度,那么会被裁剪,然后将裁剪的部分均匀分布到其他的bin,这样就重构了直方图。

     

     

     

     

     

     

    展开全文
  • python opencv 增强对比

    万次阅读 2018-11-29 09:32:12
    #opencv的直方图均衡化要基于单通道灰度图像 # cv.namedWindow('input_image', cv.WINDOW_NORMAL) # cv.imshow('input_image', gray) dst = cv . equalizeHist ( gray ) #自动调整图像对比度,把图像变得...
  • 由于用opencv自带的函数adaptiveThreshold()在光照不均匀的图像中进行二值化时,效果不佳,之后看了Derek Bradley和Gerhard Roth于2007年写的《Adaptive Thresholding Using the Integral Image》,方法简单实现简便...
  • 后期是把matlab转化为opencv,在此过程中,遇到的比较大的问题是HOG特征的提取问题,由于两个不用语言写的函数其输入参数的格式和编程思想有较多不同,在调试过程中花费了较多时间,在此作对比,并详细讲述转化方法。...
  • 直方图均衡化属于数字图像...直方图均衡化是通过调整图像的灰阶分布,使得在0~255灰阶上的分布更加均衡,提高了图像的对比度,达到改善图像主观视觉效果的目的。对比度较低的图像适合使用直方图均衡化方法来增强图像...
  • OpenCV 对比度增强

    2021-03-23 15:52:12
    直方图均衡,局部自适应对比度增强(ACE adaptiveContrastEnhancement),自适应直方图均衡(CLAHE),自动对比度。 1. 直方图均衡 cv::equalizeHist(src, dst); 2. 自适应直方图均衡(CLAHE)参考 cv::Mat ...
  • opencv局部自适应阈值 二值化
  • 主要为大家详细介绍了Python+OpenCV图片局部区域像素值处理的改进版,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 本文介绍了OpenCV-Python对比度受限的自适应直方图均衡CLAHE相关知识,可以看到CLAHE比全局直方图均衡对明暗分布不均匀的图像的改善效果更好,而进行CLAHE处理时,clipLimit值越大,对暗区域的改善效果越明显,但亮...
  • 转自:http://blog.csdn.net/icvprOpenCV的feature2d module中提供了从局部图像特征(Local image feature)的检测、特征向量(feature vector)的提取,到特征...对于高维特征向量之间的匹配,OpenCV主要有两种方...
  • OpenCV进行图像相似度对比的几种办法

    万次阅读 多人点赞 2015-02-16 18:40:03
    一种基于局部方差和结构相似度的图像质量评价方法[J]. 光电子激光,2008。 [3] http://www.cnblogs.com/vincent2012/archive/2012/10/13/2723152.html 官方文档的说明,不过是GPU版本的,我们可以修改不用gpu...
  • 校正前后效果如下 原文链接:http://www.ipol.im/pub/art/2011/gl_lcc/?utm_source=doi 中文翻译参考:... 代码实现: ...///////////////////////////////局部gamma校正/////////////////...
  • 一、理论  图像增强算法的基本原则是“降低低频区域,突出高频区域”,以此强化边缘...但是为了避免背景的干扰,更倾向于采用“局部”方法进行处理。我们这里着重研究自适应对比度增强(ACE)的相关内容。  ACE的定义和
  • python+opencv: 论文插图局部放大并拼接

    多人点赞 热门讨论 2021-10-05 14:58:24
    在制作论文插图时,有时要求将图片的局部放大来展示细节内容,同时将放大图拼接在原图上以方便观察对比。 当然直接利用电脑自带的画图软件或者别的软件也可以很方便地实现,但是如果碰到多个算法处理一张图片后多张...
  • OpenCV

    2019-11-11 23:30:45
    title:OpenCV time:2019年9月7日09:46:56 OpenCV基础1: 介绍 是计算机视觉开源库,主要算法设计图像处理和机器学习相关方法。 在多数图像相关的应用程序中被采用个,BSD许可,可以免费应用在商业和研究领域 ...
  • OpenCV全局/局部阀值二值化

    千次阅读 2017-09-22 17:06:53
    局部范围内根据特定算法算出局部的阀值,这个局部的大小可以自己决定(例8*8),算法也可以自己觉得,本文所用的用法是局部平局的灰度值作为阀值。得到局部阀值再进行局部二值化处理 2.局部二值化结果 3.完整...
  • OpenCV特征点检测算法对比

    万次阅读 2015-04-01 13:32:55
    分类: 图像处理算法2009-06-20 20:5454441人阅读评论(10)收藏举报 算法blog活动 识别算法概述: SIFT/SURF基于灰度图, 一、首先建立图像金字塔,形成三维的图像空间,通过Hessian矩阵获取每一层的局部极大值,然后...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,026
精华内容 2,410
关键字:

opencv局部对比