• 线性变换是灰度变换的一种,图像的灰度变换通过建立灰度映射来调整源图像的灰度从而达到图像增强的目的。  其公式可以表示为y(x, y) = k * x(x, y) + b;其中y(x, y)表示目标像素值,x(x, y)表示源像素值,k表示...
    线性变换是灰度变换的一种,图像的灰度变换通过建立灰度映射来调整源图像的灰度从而达到图像增强的目的。
    

         其公式可以表示为y(x, y) = k * x(x, y) + b;其中y(x, y)表示目标像素值,x(x, y)表示源像素值,k表示斜率,b表示截距。 

        1)当k>1时,可用于增加图像的对比度。图像的像素值在变换后全部增大,整体显示效果被增强。

        2)当k=1时,常用于调节图像亮度。

        3)当0<k<1时,效果与k>1时刚刚相反,图像的对比度和整体效果都被削弱。

        4)当k<0时,源图像较亮的区域变暗,而较暗的区域会变亮。此时可以使函数中的k=-1,d=255让图像实现反色效果。

         代码如下:

    1. /******************************************************************************    
    2. *   作用:     线性变换函数
    3. *   参数: pDst     输出图像的像素数组
    4. *   参数: pSrc     原始图像的像素数组
    5. *   参数: nWidth   原始图像宽度
    6. *   参数: nHeight  原始图像高度
    7. *   参数: slope      线性函数的斜率
    8. *   参数: inter      线性函数的截距
    9. *   备注: 此函数对于彩色图同样适用
    10. ******************************************************************************/ 
    11. int LineTrans(BYTE* pDst, BYTE* pSrc, int nWidth, int nHeight, double slope, double inter) 
    12.     if (!pSrc || !pDst) 
    13.     { 
    14.         return EXIT_FAILURE; 
    15.     } 
    16.  
    17.     // 灰度映射表 
    18.     BYTE map[256]; 
    19.  
    20.     // 保存运算后的临时值 
    21.     double dTemp; 
    22.     int i, j; 
    23.     for (i = 0; i < 256; i++) 
    24.     { 
    25.         // 计算当前像素变换后的值 
    26.         dTemp = slope * i + inter; 
    27.  
    28.         // 如果超界则修改其值 
    29.         if (dTemp < 0) 
    30.             dTemp = 0.0; 
    31.         else if (dTemp > 255) 
    32.             dTemp = 255; 
    33.  
    34.         // 四舍五入 
    35.         map[i] = int(dTemp + 0.5); 
    36.     } 
    37.  
    38.     // 线性变换后的值直接在映射表中查找 
    39.     for (i = 0; i < nWidth * nHeight; i++) 
    40.     {    
    41.         for (j = 0; j < 4; j++) 
    42.             pDst[i*4 + j] = map[pSrc[i*4 + j]]; 
    43.     } 
    44.     return EXIT_SUCCESS; 

      

    展开全文
  • 前面讲过的“非0即1法”,固定阈值法,双固定阈值法等都属于非线性变换。这里再补充几种常用的非线性变换。 一、灰度对数变换  对数变换实现了图像的灰度扩展和压缩的功能。它扩展低灰度值而压缩高灰度值,让图像...

            这是一种输出灰度级与输入灰度级呈非线性关系的点运算。前面讲过的“非0即1法”,固定阈值法,双固定阈值法等都属于非线性变换。这里再补充几种常用的非线性变换。

    一、灰度对数变换

            对数变换实现了图像的灰度扩展和压缩的功能。它扩展低灰度值而压缩高灰度值,让图像的分布更加符合人的视觉特征。

     

    灰度对数变换公式如下(图像就不画了,不同的a和b产生不同的对数图像,对图像的扩展和压缩也相应改变)

     

                                                        y = a+log(1+x)/b

    下面的例子中我们取a = 10,b = 0.025

    思路:

    1. 传入需要处理的图像    
    2. 遍历整个图像取出图像中每个点的像素值存到一个数组中(oldPix)
    3. 在循环中获取每个像素点的颜色值,并抽取每个像素中的r,g,b,a分量准备处理
    4. 利用灰度公式计算出每个点的灰度值(范围0-255),并做溢出处理
    5. 令某点的灰度值gray = log(gray+1)/0.025+10
    6. 如果某点的灰度值小于阈值下限则将其灰度值置为0
    7. 如果某点的灰度值大于阈值上限则将其灰度值置为255
    8. 将处理后的灰度值合成像素点的颜色值,存到一个新数组中(newPix)
    9. 创建一个高度、宽度和原图完全一样的新图
    10. 将新图像返回
       private Bitmap logarithm(Bitmap bm) {
            int width = bm.getWidth();//原图像宽度
            int height = bm.getHeight();//原图高度
            int color;//用来存储某个像素点的颜色值
            int gray;//用来存储计算得到的灰度值
            int r, g, b, a;//红,绿,蓝,透明度
            //创建空白图像,宽度等于原图宽度,高度等于原图高度,用ARGB_8888渲染,这个不用了解,这样写就行了
            Bitmap bmp = Bitmap.createBitmap(width, height
                    , Bitmap.Config.ARGB_8888);
    
            int[] oldPx = new int[width * height];//用来存储原图每个像素点的颜色信息
            int[] newPx = new int[width * height];//用来处理处理之后的每个像素点的颜色信息
            /**
             * 第一个参数oldPix[]:用来接收(存储)bm这个图像中像素点颜色信息的数组//The array to receive the bitmap’s colors
             * 第二个参数offset:oldPix[]数组中第一个接收颜色信息的下标值// The first index to write into pixels[]
             * 第三个参数width:在行之间跳过像素的条目数,必须大于等于图像每行的像素数//The number of entries in pixels[] to skip between rows (must be >= bitmap’s width). Can be negative.
             * 第四个参数x:从图像bm中读取的第一个像素的横坐标 The x coordinate of the first pixel to read from the bitmap
             * 第五个参数y:从图像bm中读取的第一个像素的纵坐标The y coordinate of the first pixel to read from the bitmap
             * 第六个参数width:每行需要读取的像素个数The number of pixels to read from each row
             * 第七个参数height:需要读取的行总数The number of rows to read
             */
            bm.getPixels(oldPx, 0, width, 0, 0, width, height);
    
            for (int i = 0; i < width * height; i++) {//循环处理图像中每个像素点的颜色值
                color = oldPx[i];//取得某个点的像素值
                r = Color.red(color);//取得此像素点的r(红色)分量
                g = Color.green(color);//取得此像素点的g(绿色)分量
                b = Color.blue(color);//取得此像素点的b(蓝色分量)
                a = Color.alpha(color);//取得此像素点的a通道值
                //此公式将r,g,b运算获得灰度值,经验公式不需要理解
                gray = (int)((float)r*0.3+(float)g*0.59+(float)b*0.11);
    
                gray = (int)(Math.log((float)gray + 1.0f)/0.025f + 10.0f);
                //溢出处理
                if(gray < 0) {
                    gray = 0;
                } else if(gray > 255) {
                    gray = 255;
                }
    
                newPx[i] = Color.argb(a,gray,gray,gray);
            }
            bmp.setPixels(newPx, 0, width, 0, 0, width, height);//将处理后的透明度(没变),r,g,b分量重新合成颜色值并将其存储在数组中
            return bmp;//返回处理后的图像
        }

    效果

    二、灰度指数变换

            指数变换的作用是扩展图像的高灰度级,压缩低灰度级。虽然幂次变换也有这个功能,但是图像经过指数变换后对比度更高,高灰度级也扩展到了更宽的范围。 

     

    灰度指数变换的基本公式如下

    下面的例子中我们取b = 1.5,c = 0.065,a = 0

    思路:

    1. 传入需要处理的图像    
    2. 遍历整个图像取出图像中每个点的像素值存到一个数组中(oldPix)
    3. 在循环中获取每个像素点的颜色值,并抽取每个像素中的r,g,b,a分量准备处理
    4. 利用灰度公式计算出每个点的灰度值(范围0-255),并做溢出处理
    5. 令某点的灰度值gray = 1.5^{0.065*(gray-0)}-1
    6. 如果某点的灰度值小于阈值下限则将其灰度值置为0
    7. 如果某点的灰度值大于阈值上限则将其灰度值置为255
    8. 将处理后的灰度值合成像素点的颜色值,存到一个新数组中(newPix)
    9. 创建一个高度、宽度和原图完全一样的新图
    10. 将新图像返回
       private void exponetial(Bitmap bm) {
            int width = bm.getWidth();//原图像宽度
            int height = bm.getHeight();//原图高度
            int color;
            int r, g, b, a;
    
            Bitmap bmp = Bitmap.createBitmap(width, height
                    , Bitmap.Config.ARGB_8888);
    
            int[] oldPx = new int[width * height];
            int[] newPx = new int[width * height];
            bm.getPixels(oldPx, 0, width, 0, 0, width, height);
    
            for (int i = 0; i < width * height; i++) {
                color = oldPx[i];
                r = Color.red(color);
                g = Color.green(color);
                b = Color.blue(color);
                a = Color.alpha(color);
    
                int gray = (int)((float)r*0.3+(float)g*0.59+(float)b*0.11);
                gray = (int)(Math.pow(1.5f,0.065f * (gray - 0)) - 1.0f);
                if(gray < 0) {
                    gray = 0;
                } else if(gray > 255) {
                    gray = 255;
                }
    
                newPx[i] = Color.argb(a,gray,gray,gray);
            }
            bmp.setPixels(newPx, 0, width, 0, 0, width, height);
            mImageView.setImageBitmap(bmp);
        }

    效果

     

     

     

     

     

     

     

     

     

     

    三、灰度幂次变换

            幂次变换将部分灰度区域映射到更宽的区域中。

     

    灰度幂次变换的基本公式如下(取r = 1时变为线性变换)

    由于直接进行幂次变换会使大部分像素的灰度值超过255,因此我们先将某点的灰度值除以255,进行灰度变换后再将结果乘以255。

    思路

    1. 传入需要处理的图像    
    2. 遍历整个图像取出图像中每个点的像素值存到一个数组中(oldPix)
    3. 在循环中获取每个像素点的颜色值,并抽取每个像素中的r,g,b,a分量准备处理
    4. 利用灰度公式计算出每个点的灰度值(范围0-255),并做溢出处理
    5. 令某点的灰度值gray = (gray/255)^{1.7}*255+20
    6. 如果某点的灰度值小于阈值下限则将其灰度值置为0
    7. 如果某点的灰度值大于阈值上限则将其灰度值置为255
    8. 将处理后的灰度值合成像素点的颜色值,存到一个新数组中(newPix)
    9. 创建一个高度、宽度和原图完全一样的新图
    10. 将新图像返回
        private void power(Bitmap bm) {
            int width = bm.getWidth();
            int height = bm.getHeight();
            int color;
            int r, g, b, a;
    
            Bitmap bmp = Bitmap.createBitmap(width, height
                    , Bitmap.Config.ARGB_8888);
    
            int[] oldPx = new int[width * height];
            int[] newPx = new int[width * height];
            bm.getPixels(oldPx, 0, width, 0, 0, width, height);
    
            for (int i = 0; i < width * height; i++) {
                color = oldPx[i];
                r = Color.red(color);
                g = Color.green(color);
                b = Color.blue(color);
                a = Color.alpha(color);
    
                int gray = (int)((float)r*0.3+(float)g*0.59+(float)b*0.11);
                gray = (int)(1.0f * Math.pow(gray/255.0f,1.7f) * 255 + 20);
                if(gray < 0) {
                    gray = 0;
                } else if(gray > 255) {
                    gray = 255;
                }
    
                newPx[i] = Color.argb(a,gray,gray,gray);
            }
            bmp.setPixels(newPx, 0, width, 0, 0, width, height);
            mImageView.setImageBitmap(bmp);
        }

    效果

     

     代码已上传到github,点击这里可以下载体验

    展开全文
  • 前一篇文章讲解了图像灰度化处理线性变换知识,结合OpenCV调用cv2.cvtColor()函数实现图像灰度操作,本篇文章主要讲解非线性变换,使用自定义方法对图像进行灰度化处理,包括对数变换和伽马变换。本文主要讲解灰度...

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。希望文章对您有所帮助,如果有不足之处,还请海涵~

    该系列在github所有源代码:https://github.com/eastmountyxz/ImageProcessing-Python
    PS:请求帮忙点个Star,哈哈,第一次使用Github,以后会分享更多代码,一起加油。

    同时推荐作者的C++图像系列知识:
    [数字图像处理] 一.MFC详解显示BMP格式图片
    [数字图像处理] 二.MFC单文档分割窗口显示图片
    [数字图像处理] 三.MFC实现图像灰度、采样和量化功能详解
    [数字图像处理] 四.MFC对话框绘制灰度直方图
    [数字图像处理] 五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理详解
    [数字图像处理] 六.MFC空间几何变换之图像平移、镜像、旋转、缩放详解
    [数字图像处理] 七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解

    前文参考:
    [Python图像处理] 一.图像处理基础知识及OpenCV入门函数
    [Python图像处理] 二.OpenCV+Numpy库读取与修改像素
    [Python图像处理] 三.获取图像属性、兴趣ROI区域及通道处理
    [Python图像处理] 四.图像平滑之均值滤波、方框滤波、高斯滤波及中值滤波
    [Python图像处理] 五.图像融合、加法运算及图像类型转换
    [Python图像处理] 六.图像缩放、图像旋转、图像翻转与图像平移
    [Python图像处理] 七.图像阈值化处理及算法对比
    [Python图像处理] 八.图像腐蚀与图像膨胀
    [Python图像处理] 九.形态学之图像开运算、闭运算、梯度运算
    [Python图像处理] 十.形态学之图像顶帽运算和黑帽运算
    [Python图像处理] 十一.灰度直方图概念及OpenCV绘制直方图
    [Python图像处理] 十二.图像几何变换之图像仿射变换、图像透视变换和图像校正
    [Python图像处理] 十三.基于灰度三维图的图像顶帽运算和黑帽运算
    [Python图像处理] 十四.基于OpenCV和像素处理的图像灰度化处理
    [Python图像处理] 十五.图像的灰度线性变换

    前一篇文章讲解了图像灰度化处理及线性变换知识,结合OpenCV调用cv2.cvtColor()函数实现图像灰度操作,本篇文章主要讲解非线性变换,使用自定义方法对图像进行灰度化处理,包括对数变换和伽马变换。本文主要讲解灰度线性变换,基础性知识希望对您有所帮助。
    1.图像灰度非线性变换:DB=DA×DA/255
    2.图像灰度对数变换
    3.图像灰度伽玛变换

    PS:文章参考自己以前系列图像处理文章及OpenCV库函数,同时参考如下文献:
    杨秀璋等. 基于苗族服饰的图像锐化和边缘提取技术研究[J]. 现代计算机,2018(10).
    《数字图像处理》(第3版),冈萨雷斯著,阮秋琦译,电子工业出版社,2013年.
    《数字图像处理学》(第3版),阮秋琦,电子工业出版社,2008年,北京.
    《OpenCV3编程入门》,毛星云,冷雪飞,电子工业出版社,2015.
    [数字图像处理] 五.MFC图像点运算之灰度线性变化、灰度非线性变化、阈值化和均衡化处理详解
    python+opencv+图像特效(图像灰度处理、颜色翻转、图片融合,边缘检测,浮雕效果)
    数字图像处理-空间域处理-灰度变换-基本灰度变换函数
    OpenCV图像增强算法实现(直方图均衡化、拉普拉斯、Log、Gamma)


    一.图像灰度非线性变换:DB=DA×DA/255

    图像的灰度非线性变换主要包括对数变换、幂次变换、指数变换、分段函数变换,通过非线性关系对图像进行灰度处理,下面主要讲解三种常见类型的灰度非线性变换。

    原始图像的灰度值按照DB=DA×DA/255的公式进行非线性变换,其代码如下:

    # -*- coding: utf-8 -*-
    import cv2  
    import numpy as np  
    import matplotlib.pyplot as plt
    
    #读取原始图像
    img = cv2.imread('miao.png')
    
    #图像灰度转换
    grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    #获取图像高度和宽度
    height = grayImage.shape[0]
    width = grayImage.shape[1]
    
    #创建一幅图像
    result = np.zeros((height, width), np.uint8)
    
    #图像灰度非线性变换:DB=DA×DA/255
    for i in range(height):
        for j in range(width):
            gray = int(grayImage[i,j])*int(grayImage[i,j]) / 255
            result[i,j] = np.uint8(gray)
    
    #显示图像
    cv2.imshow("Gray Image", grayImage)
    cv2.imshow("Result", result)
    
    #等待显示
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    图像灰度非线性变换的输出结果下图所示:


    二.图像灰度对数变换

    图像灰度的对数变换一般表示如公式所示:

    其中c为尺度比较常数,DA为原始图像灰度值,DB为变换后的目标灰度值。如下图所示,它表示对数曲线下的灰度值变化情况。

    由于对数曲线在像素值较低的区域斜率大,在像素值较高的区域斜率较小,所以图像经过对数变换后,较暗区域的对比度将有所提升。这种变换可用于增强图像的暗部细节,从而用来扩展被压缩的高值图像中的较暗像素。

    对数变换实现了扩展低灰度值而压缩高灰度值的效果,被广泛地应用于频谱图像的显示中。一个典型的应用是傅立叶频谱,其动态范围可能宽达0~106直接显示频谱时,图像显示设备的动态范围往往不能满足要求,从而丢失大量的暗部细节;而在使用对数变换之后,图像的动态范围被合理地非线性压缩,从而可以清晰地显示。在下图中,未经变换的频谱经过对数变换后,增加了低灰度区域的对比度,从而增强暗部的细节。

    下面的代码实现了图像灰度的对数变换。

    # -*- coding: utf-8 -*-
    import numpy as np
    import matplotlib.pyplot as plt
    import cv2
    
    #绘制曲线
    def log_plot(c):
        x = np.arange(0, 256, 0.01)
        y = c * np.log(1 + x)
        plt.plot(x, y, 'r', linewidth=1)
        plt.rcParams['font.sans-serif']=['SimHei'] #正常显示中文标签
        plt.title(u'对数变换函数')
        plt.xlim(0, 255), plt.ylim(0, 255)
        plt.show()
    
    #对数变换
    def log(c, img):
        output = c * np.log(1.0 + img)
        output = np.uint8(output + 0.5)
        return output
    
    #读取原始图像
    img = cv2.imread('test.png')
    
    #绘制对数变换曲线
    log_plot(42)
    
    #图像灰度对数变换
    output = log(42, img)
    
    #显示图像
    cv2.imshow('Input', img)
    cv2.imshow('Output', output)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    下图表示经过对数函数处理后的效果图,对数变换对于整体对比度偏低并且灰度值偏低的图像增强效果较好。

    对应的对数函数曲线如图


    三.图像灰度伽玛变换

    伽玛变换又称为指数变换或幂次变换,是另一种常用的灰度非线性变换。图像灰度的伽玛变换一般表示如公式所示:

    • 当γ>1时,会拉伸图像中灰度级较高的区域,压缩灰度级较低的部分。
    • 当γ<1时,会拉伸图像中灰度级较低的区域,压缩灰度级较高的部分。
    • 当γ=1时,该灰度变换是线性的,此时通过线性方式改变原图像。

    Python实现图像灰度的伽玛变换代码如下,主要调用幂函数实现。

    # -*- coding: utf-8 -*-
    import numpy as np
    import matplotlib.pyplot as plt
    import cv2
    
    #绘制曲线
    def gamma_plot(c, v):
        x = np.arange(0, 256, 0.01)
        y = c*x**v
        plt.plot(x, y, 'r', linewidth=1)
        plt.rcParams['font.sans-serif']=['SimHei'] #正常显示中文标签
        plt.title(u'伽马变换函数')
        plt.xlim([0, 255]), plt.ylim([0, 255])
        plt.show()
    
    #伽玛变换
    def gamma(img, c, v):
        lut = np.zeros(256, dtype=np.float32)
        for i in range(256):
            lut[i] = c * i ** v
        output_img = cv2.LUT(img, lut) #像素灰度值的映射
        output_img = np.uint8(output_img+0.5)  
        return output_img
    
    #读取原始图像
    img = cv2.imread('test.png')
    
    #绘制伽玛变换曲线
    gamma_plot(0.00000005, 4.0)
    
    #图像灰度伽玛变换
    output = gamma(img, 0.00000005, 4.0)
    
    #显示图像
    cv2.imshow('Imput', img)
    cv2.imshow('Output', output)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    下图表示经过伽玛变换处理后的效果图,伽马变换对于图像对比度偏低,并且整体亮度值偏高(或由于相机过曝)情况下的图像增强效果明显。

    对应的幂律函数曲线如图所示。


    文章周日写于钟书阁,女神伴于旁。希望文章对大家有所帮助,如果有错误或不足之处,还请海涵。最近连续奔波考博,经历的事情太多,有喜有悲,需要改变自己好好对女神,也希望读者与我一起加油。

    (By:Eastmount 2019-03-31 深夜12点 https://blog.csdn.net/Eastmount/)

    展开全文
  • 1、分段线性变换各种情况的变换效果对比 2、对数、指数变换、取反等多种非线性变换的效果对比 变换结果与分析 分段线性变换 1)变换函数 2)分段线性变换结果 3)分段线性变换对比分析 通过变换,将灰度...

    变换目标

    1、分段线性变换各种情况的变换效果对比
    2、对数、指数变换、取反等多种非线性变换的效果对比

    变换结果与分析

    分段线性变换
    1)变换函数
    在这里插入图片描述
    2)分段线性变换结果
    在这里插入图片描述
    3)分段线性变换对比分析
    通过变换,将灰度值小于82的变小,将灰度值大于173的增大,处于82与173之间的被拉伸。
    对数变换
    1)变换函数

    在这里插入图片描述
    2)对数变换结果
    在这里插入图片描述
    3)对数变换分析
    低灰度值区域被拉伸,高灰度值区域被缩小,常数c越大,图像灰度值越集中于255,常数c越接近0,图像灰度值越接近于0.
    指数变换
    1)变换函数
    在这里插入图片描述
    2)指数变换结果
    在这里插入图片描述
    3)指数变换分析:
    当指数大于1,图像灰度值减小,当指数小于1大于0,回想灰度值增大。
    取反变换
    1)取反变换函数
    在这里插入图片描述
    2)取反变换结果
    在这里插入图片描述
    3)取反变换对比分析
    增强了图像暗色区域中的白色或灰色细节,特别是黑色面积在尺寸上占主导地位的时候,效果逐渐明显。

    代码

    分段线性变换

    %Write  by 长安 Rjex
    %分段线性变换各种情况的变换效果对比
    %name为图像文件名,(r1,s1),(r2,s2)为变换点
    function B = pielinear(name,r1,s1,r2,s2)I = imread(name); 
    if r1>r2||s1>s2
       error(message('MATLAB:pieLinear:invalidCoordinate'))
    end 
    A=rgb2gray(I);B = A; %确定分段函数方程
    syms k b;
    [k1,b1] =solve([k*r1+b==s1, 0*k+b==0], k,b);
    [k2,b2] =solve([k*r2+b==s2, k*r1+b==s1], [k,b]);
    [k3,b3] =solve([k*r2+b==s2, k*255+b==255], [k,b]); %符号变量转换成数值常量
    k1 = double(k1);
    k2 = double(k2);
    k3 = double(k3);
    b1 = double(b1);
    b2 = double(b2);b3 = double(b3); %分段线性变换
    for i = 1 : size(A,1)
        for j = 1 : size(A,2)    
            if A(i,j)<=r1       
                 B(i,j) = double(A(i,j))*k1+b1; %此处须将A浮点化,否则对A的算术运算范围为0~255        
            elseif 
                 A(i,j)>r1&&A(i,j)<=r2            
                 B(i,j) = double(A(i,j))*k2+b2;        
             else            
                 B(i,j) = double(A(i,j))*k3+b3;        
             end    
         end
    end %原图与对比度拉伸后的图像
    
    figure(1);
    subplot(2,2,1),imshow(A),title('(a)原始图像');
    subplot(2,2,2),imhist(A),title('(b)原始直方图');
    subplot(2,2,3),imshow(B),title('(c)分段线性变换后的图像');
    subplot(2,2,4),imhist(B),title('(d)分段线性变换后的直方图'); %分段函数的表示
    
    figure(2);
    x=0:1:255;y=(k1*x+b1).*(x>=0&x<=r1)+(k2*x+b2).*(x>r1&x<=r2)+(k3*x+b3).*(x>r2&x<=255);plot(x,y);axis([0 255 0 255]),title('分段函数'),xlabel('r'),ylabel('T(r)'); 

    反转(取反)变换

    %Write  by 长安 Rjex
    %图像反转的变换效果对比%name为图像文件名
    function B = negatrans(name)I = imread(name);
    A=rgb2gray(I);
    B = A; %图像反转
    for i = 1 : size(A,1)
        for j = 1 : size(A,2)      
              B(i,j) = 255-double(A(i,j));
               %此处须将A浮点化,否则对A的算术运算范围为0~255    
        end
    end %原图与图像反转后的图像
    
    figure(1);
    subplot(2,2,1),imshow(A),title('(a)原始图像');
    subplot(2,2,2),imhist(A),title('(b)原始直方图');
    subplot(2,2,3),imshow(B),title('(c)反转后的图像');
    subplot(2,2,4),imhist(B),title('(d)反转后的直方图'); %反转函数的表示
    
    figure(2);
    x=0:1:255;y=255-x;plot(x,y),axis([0 255 0 255]),title('反转函数'),xlabel('r'),ylabel('T(r)'); 

    对数变换

    %Write  by 长安 Rjex
    %对数变换各种情况的变换效果对比%name为图像文件名,c为对数变换中的常数,即:clog(r+1)
    function B = logtrans(name,c)I = imread(name); 
    A=rgb2gray(I);B = A; %对数变换
    for i = 1 : size(A,1)
        for j = 1 : size(A,2)       
             B(i,j) = c*log(double(A(i,j))+1); %此处须将A浮点化,否则对A的算术运算范围为0~255    
        end
    end %原图与对数变换后的图像
    
    figure(1);
    subplot(2,2,1),imshow(A),title('(a)原始图像');
    subplot(2,2,2),imhist(A),title('(b)原始直方图');
    subplot(2,2,3),imshow(B),title('(c)对数变换后的图像');
    subplot(2,2,4),imhist(B),title('(d)对数变换后的直方图'); %对数函数的表示
    
    figure(2);
    x=0:1:255;y=c*log(x+1);plot(x,y);axis([0 255 0 255]),title('对数函数'),xlabel('r'),ylabel('T(r)'); 

    指数变换

    %Write  by 长安 Rjex
    %指数变换各种情况的变换效果对比%name为图像文件名
    function B = indextrans(name,c,r)
    I = imread(name); 
    A=rgb2gray(I);B = A; %指数变换
    for i = 1 : size(A,1)
        for j = 1 : size(A,2)       
             B(i,j) = (double(A(i,j))^r.*c)/(255^r)*255; %此处须将A浮点化,否则对A的算术运算范围为0~255    
        end
    end %原图与指数变换后的图像
    
    figure(1);
    subplot(2,2,1),imshow(A),title('(a)原始图像');
    subplot(2,2,2),imhist(A),title('(b)原始直方图');
    subplot(2,2,3),imshow(B),title('(c)指数变换后的图像');
    subplot(2,2,4),imhist(B),title('(d)指数变换后的直方图'); %指数函数的表示
    
    figure(2);
    x=0:1:255;y=(x.^r.*c)/(255^r)*255;plot(x,y);axis([0 255 0 255]),title('指数函数'),xlabel('r'),ylabel('T(r)');
    展开全文
  • 图像灰度非线性变换 文章目录1 原理2 Matlab实现3 OpenCV实现3.1 实现3.2 注意4 效果图 1 原理   图像灰度的非线性变换主要有对数变换、指数变换、幂次变换等。本文主要讨论对数变换。   对数变换的基本形式...

    图像灰度非线性变换

    1 原理

      图像灰度的非线性变换主要有对数变换、指数变换、幂次变换等。本文主要讨论对数变换。

      对数变换的基本形式如下:
    y=log(1+x)b y=\frac{\log{(1+x)}}{b}
    其中,bb为正常数,用以控制曲线的弯曲程度。

      对数变换实现了图像灰度扩展和压缩的功能,它扩展低灰度值而压缩高灰度值。

    2 Matlab实现

    clc;
    clear;
    close all;
    
    % 对灰度图进行灰度线性变换
    ori_img = imread('../images/6.jpg');
    ori_img1 = rgb2gray(ori_img);
    [oriHist,oriX] = imhist(ori_img1);
    ori_img = double(ori_img1);
    
    k = 1.25;
    d = 0;
    gray1 = log(1+ori_img) /0.065;
    gray1(find(gray1>255))=255;
    gray1=uint8(gray1);
    [g1Hist,g1X] = imhist(gray1);
    
    
    figure(1),subplot(1,2,1),imshow(ori_img1),title('原图');subplot(1,2,2),imshow(gray1),title('k>0 d=0');
    figure(2),subplot(1,2,1),stem(oriX,oriHist),title('原图直方图');subplot(1,2,2),stem(g1X,g1Hist),title('k>0 d=0直方图');
    
    

    3 OpenCV实现

    3.1 实现

    #include <iostream>
    #include <string>
    
    #include "../include/opencv400/opencv2/opencv.hpp"
    #include "../include/opencv400/opencv2/core.hpp"
    #include "windows.h"
    
    std::string g_CurrentDirectory;
    void SetCurrentDirectoryToExePath()
    {
    	HMODULE hExe = GetModuleHandleA(NULL);
    	char nameBuf[MAX_PATH] = { 0 };
    	GetModuleFileNameA(hExe, nameBuf, MAX_PATH);
    	std::string sName(nameBuf);
    	sName = sName.substr(0, sName.rfind('\\'));
    	SetCurrentDirectoryA(sName.c_str());
    	g_CurrentDirectory = sName;
    }
    
    
    void calcHist1D(cv::Mat& input, cv::Mat& output)
    {
    	int channels[] = { 0 };
    	int histsize[] = { 256 };
    	float grayRnage[] = { 0,256 };
    	const float* ranges[] = { grayRnage };
    	cv::MatND hist;
    	cv::calcHist(&input, 1, channels, cv::Mat(), hist, 1, histsize, ranges);
    
    	double maxVal = 0;
    	cv::minMaxLoc(hist, 0, &maxVal, 0, 0);
    
    	int scale = 10;
    	output = cv::Mat::zeros(500, 257 * 5, CV_8UC3);
    
    	//std::cout << "-----------------------------------" << std::endl;
    	for (int i = 0; i < histsize[0]; i++)
    	{
    		float binVal = hist.at<float>(i, 0);
    		//std::cout << i << " " << binVal << std::endl;
    		int intensity = cvRound(binVal * 500 / maxVal);
    		rectangle(output, cv::Point(i * 5, 500 - intensity),
    			cv::Point((i + 1) * 5, 500),
    			cv::Scalar::all(255),
    			-1);
    	}
    
    }
    
    int main()
    {
    	SetCurrentDirectoryToExePath();
    
    	cv::Mat ori_img = cv::imread("../images/6.jpg");
    	cv::Mat gray_img;
    	cv::cvtColor(ori_img, gray_img, cv::COLOR_BGR2GRAY);
    	cv::namedWindow("灰度图");
    	cv::imshow("灰度图", gray_img);
    
    	cv::Mat grayHist;
    	calcHist1D(gray_img, grayHist);
    	cv::imshow("hist", grayHist);
    
    	gray_img.convertTo(gray_img, CV_32FC1, 1.0 );
    
    	cv::Mat g1;
    	cv::log(1 + gray_img,g1);
    	g1 = g1 / 0.025;
    
    	cv::Mat m255(gray_img.rows, gray_img.cols, CV_32FC1);
    	m255 = cv::Scalar(255);
    #undef min
    	cv::min(g1, m255, g1);
    	g1.convertTo(g1, CV_8UC1);
    	cv::Mat g1Hist;
    	calcHist1D(g1, g1Hist);
    	cv::imshow("g1Hist", g1Hist);
    	imshow("dd", g1);
    
    	
    
    	cv::waitKey();
    	return 0;
    }
    

    3.2 注意

      OpenCV中提供了对cv::Matlog,sqrt,min,max等操作,在core.hpp文件中。使用min函数可以实现对Mat中各元素超过阈值进行截断的功能。
    例如,在上述实现中,对g1超过255的值进行截断,赋值为255.通过以下代码实现。

    	cv::Mat m255(gray_img.rows, gray_img.cols, CV_32FC1);
    	m255 = cv::Scalar(255);
    #undef min
    	cv::min(g1, m255, g1);
    

    注意其中的#undef min,由于定义了宏min,导致在调用cv::min函数的时候会编译错误。

    4 效果图

    在这里插入图片描述在这里插入图片描述

    展开全文
  • 图像的灰度线性变换 图像增强:线性、 分段线性、 对数、 反对数、 幂律(伽马)变换、直方图均衡. 感谢各位博主分享,侵删 关于OpenCV和numpy模块 需要先导入cv2和numpy库,我的pycharm已经安装了anacond...
  • 图像灰度线性变换 文章目录1 概念2 原理3 作用4 Matlab实现5 OpenCV实现6 效果图6.1 效果图7 讨论 1 概念   灰度线性变换是一种灰度变换,通过建立灰度映射来调整源图像的灰度,达到图像增强的目的。灰度映射...
  • 图像处理开发资料、图像处理开发需求、图像处理接私活挣零花钱,可以搜索公众号"qxsf321",并关注! 图像处理开发资料、图像处理开发需求、图像处理接私活挣零花钱,可以搜索公众号"qxsf321",...
  • 前一篇文章讲解了图像灰度化处理的知识,结合OpenCV调用cv2.cvtColor()函数实现图像灰度操作,使用像素处理方法对图像进行灰度化处理。本文主要讲解灰度线性变换,基础性知识希望对您有所帮助。 1.图像灰度上移变换...
  • 本系列python版本:python3.5.4 本系列opencv-python版本:opencv-python3.4.2.17 本系列使用的开发环境是jupyter notebook,是一个python的交互式开发环境,测试十分方便,并集成了...上文【数字图像处理系列二...
  • 图像点处理是图像处理系列的基础,主要用于让我们熟悉Matlab图像处理的编程环境。灰度线性变换和灰度拉伸是对像素灰度值的变换操作,直方图是对像素灰度值的统计,直方图均衡是对灰度值分布的变换
  • 线性变换 直观定义 几种基本线性变换与对应的矩阵表示 旋转 翻转镜像 缩放伸缩 推移错切 仿射变换 投影变换 总结平面变换包括 线性变换,仿射变换等, 线性变换包括 旋转,镜像(翻转),伸缩(缩放),推移(错切) ...
  • 灰度变换图像增强的一种重要手段,用于改善图像显示效果,属于空间域处理方法,它可以使图像动态范围加大,使图像对比度扩展,图像更加清晰,特征更加明显。灰度变换其实质就是按一定的规则修改图像每一个像素的...
  • 图像灰度线性变换 假定原图像f(x,y)f(x,y)f(x,y)的灰度范围为[a,b],变换后图像g(x,y)g(x,y)g(x,y)灰度扩展为[c,d],则根据线性方程式可以得到: (9-1)g(x,y)=d−cb−a[f(x,y)−a]+c g(x,y) = \frac{d - c}{b - a}[f...
  • 灰度的线性变换 Db = f(Da) = k*Da +b k为斜率,b为y轴交点截距,Da为输入图像的灰度,Db为输出图像的灰度 三个有趣的结论,相信会对灰度变换的理解更加深刻: 1,k> 1增加对比度,k 2,k=1改变亮度 3,k=1,b=0...
  • 图像的线性变换图像处理的基本运算,通常应用在调整图像的画面质量方面,如图像对比度、亮度及反转等操作。对于输入图像f(x,y),输出图像g(x,y),其线性变换表达式为: 其中参数a表示图像对比度变化,b表示图像...
  • 一.理论基础 线性灰度变换函数是一个线性函数:B=f(A)=aA+c.其中A为输入图像灰度值,B为输出图像灰度,a为线性函数的斜率,c为在Y轴的截距。 当a>1时,输入图像的对比度将增大,...这种线性变换可能由于像素达到...
  • 图像线性变换,是比较容易理解的。由线性变换公式y=kx+b知道,图像的像素点灰度值为x,经由线性变换输出y再替换掉原像素点的灰度值x实现映射。其作用是当图像像素的灰度值集中在一定范围如[a,b]时,可以经由线性...
  • 灰度变换法:  一般成像系统只具有一定的亮度范围,亮度的最大值与最小值之比称为...灰度变换法又可分为三种:线性分段性及分线性变换。 (1)线性变换  假定原图像f(x,y)的灰度范围为[a,b],希望变换后图像g(x,y)
1 2 3 4 5 ... 20
收藏数 44,493
精华内容 17,797