《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理

本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的、不同方法的处理,以达到对图像进行去噪、锐化等一系列的操作。同时,希望观看本专栏的小伙伴可以理解到OpenCv进行图像处理的强大哦,如有转载,请注明出处(原文链接和作者署名),感谢各位小伙伴啦!

前文参考:
《OpenCv视觉之眼》Python图像处理一 :Opencv-python的简介及Python环境搭建
《OpenCv视觉之眼》Python图像处理二 :Opencv图像读取、显示、保存基本函数原型及使用
《OpenCv视觉之眼》Python图像处理三 :Opencv图像属性、ROI区域获取及通道处理
《OpenCv视觉之眼》Python图像处理四 :Opencv图像灰度处理的四种方法及原理
《OpenCv视觉之眼》Python图像处理五 :Opencv图像去噪处理之均值滤波、方框滤波、中值滤波和高斯滤波
《OpenCv视觉之眼》Python图像处理六 :Opencv图像傅里叶变换和傅里叶逆变换原理及实现
《OpenCv视觉之眼》Python图像处理七 :Opencv图像处理之高通滤波和低通滤波原理及构造
《OpenCv视觉之眼》Python图像处理八 :Opencv图像处理之图像阈值化处理原理及函数
《OpenCv视觉之眼》Python图像处理九 :Opencv图像形态学处理之图像腐蚀与膨胀原理及方法
《OpenCv视觉之眼》Python图像处理十 :Opencv图像形态学处理之开运算、闭运算和梯度运算原理及方法
《OpenCv视觉之眼》Python图像处理十一 :Opencv图像形态学处理之顶帽运算与黑帽运算
《OpenCv视觉之眼》Python图像处理十二 :Opencv图像轮廓提取之基于一阶导数的Roberts算法、Prewitt算法及Sobel算法
《OpenCv视觉之眼》Python图像处理十三 :Opencv图像轮廓提取之基于二阶导数的Laplacian算法和LOG算法
《OpenCv视觉之眼》Python图像处理十四 :Opencv图像轮廓提取之Scharr算法和Canny算法
《OpenCv视觉之眼》Python图像处理十五 :Opencv图像处理之图像缩放、旋转和平移原理及实现
《OpenCv视觉之眼》Python图像处理十六:Opencv项目实战之图像中的硬币检测
《OpenCv视觉之眼》Python图像处理十七:Opencv图像处理实战二之图像中的物体识别并截取
《OpenCv视觉之眼》Python图像处理十八:Opencv图像处理实战三之基于OpenCV训练模型的AI人脸检测
《OpenCv视觉之眼》Python图像处理十九:Opencv图像处理实战四之通过OpenCV进行人脸口罩模型训练并进行口罩检测
《OpenCv视觉之眼》Python图像处理二十:Opencv图像美化处理之图像流年、光照、浮雕、素描、怀旧、滤镜、毛玻璃、油漆特效处理

上次博客我们讲解了图像的各种滤镜特效的处理,通过上次博客的讲解,相信大家已经对美图秀秀的某些功能开发的原理有了一定的了解,但这些特效都只是基础功能,如果有想深入学习对图像特效处理的小伙伴,可以在百度搜索各种特效的处理,是有很多种类的,结合他们的特效处理,然后融入你自己的思想,便又是一种新的特效,说不定美图秀秀官方还可能邀请你去入职呢!

本次博客,林君学长主要带大家了解图像的特殊处理——图像的线性和非线性变换处理;图像线性变换中的反色变换通常用于医学上的图像处理,而对于图像的非线性变换,在生活中的作用是非常大的,常用于解决相机曝光问题、和夜晚摄像头光线弱化问题(常用于警察通过摄像头追捕嫌疑人),当摄像头拍摄的照片光线不足而导致无法辨析嫌疑人的时候,通过可以通过图像的非线性变换增加图像灰暗部分,对查案有一定的帮助,是不是比较重要了?一起学习吧!

[Python图像处理二十一]:Opencv图像处理之图像线性变换和非线性变换的方法及原理

  • 一、图像线性变换
    • 1、图像线性变换——上移变换
    • 2、图像线性变换——对比度增强变换
    • 4、图像线性变换——反色变换
  • 二、图像非线性变换
    • 1、图像非线性——常规非线性变换
    • 2、图像非线性——对数变换
    • 3、图像非线性——伽玛变换


一、图像线性变换

图像线性变换是指针对图像的像素值做直线的变换过程,例如 y = k x + b y=kx+b y=kx+b这样的函数值,对其中的k或者b做改变的过程,不改变直线的性质,只改变直线的位置;在图像中理解就是在处理之后的图像与原始图像一一对应的像素之间存在线性变换,可以处理之后的像素是通过以上直线的方式得到的像素,如下所示:
D b = y ( D α ) = α D α + b 该 公 式 中 D b 表 示 线 性 变 换 后 的 图 像 像 素 值 , D α 表 示 变 换 前 输 入 图 像 的 像 素 值 , α 和 b 为 线 性 变 换 方 程 f ( D ) 的 参 数 , 分 别 表 示 斜 率 和 截 距 。 D_b=y(D_α)=αD_α+b\\\\该公式中D_b表示线性变换后的图像像素值,D_α表示变换前输入图像的像素值,\\\\α和b为线性变换方程f(D)的参数,分别表示斜率和截距。 Db=y(Dα)=αDα+bDb线Dααb线f(D)

  • 当α=1,b=0时,保持原始图像
  • 当α=1,b!=0时,图像所有的灰度值上移或下移
  • 当α=-1,b=255时,原始图像的灰度值反转
  • 当α>1时,输出图像的对比度增强
  • 当0<α<1时,输出图像的对比度减小
  • 当α<0时,原始图像暗区域变亮,亮区域变暗,图像求补

下面,我们分别介绍以上部分的线性变换吧,如下步骤

1、图像线性变换——上移变换

1)、原理
图像上移变换是将原始图像中的每个像素点对应的三通道的每个像素值进行上移,得到新的像素值和图像,提升图像的亮度,但上移的偏移量过大会使得图像曝光而导致图像部分区域像素损失
2)、计算公式
i m g 1 [ i , j ] = i m g [ i , j ] + u p d a t a 其 中 , i m g 1 为 图 像 上 移 之 后 的 图 像 , i m g 是 原 始 图 像 , u p d a t a 为 像 素 上 移 偏 移 量 img1[i,j]=img[i,j]+updata\\\\ 其中,img1为图像上移之后的图像,img是原始图像,updata为像素上移偏移量 img1[i,j]=img[i,j]+updataimg1imgupdata
通过以上公式,便可以进行图像线性变换上移变换的功能函数构造了,如下步骤
3)、图像线性变换之上移变换功能函数构造

'''
    图像线性变换之图像上移变换
'''
#定义图像上移变换函数
def upMove(img,upData):#上移变换的图像和上移像素
    #获取图像属性包括高、宽、通道数
    h,w,c=img.shape
    #定义空白图像,用于存放图像上移变换的结果,防止修改原图
    img1=np.zeros((h,w,c),dtype=img.dtype)
    #对原图进行遍历,通过图像上移变换原理公式对图像进行上移变换
    for i in range(h):
        for j in range(w):
            #获取原始图像个通道值并进行公式处理,然后进行防溢出处理
            b=min(255,max((img[i,j,0]+upData),0))
            g=min(255,max((img[i,j,1]+upData),0))
            r=min(255,max((img[i,j,2]+upData),0))
            #将上移变换之后的值赋值给新图像
            img1[i,j]=[b,g,r]
    return img1

4)、读取图像,进行图像上移线性变换,并展示图像效果

#导入函数库
import cv2
import numpy as np
#np.set_printoptions(threshold=np.inf)  #打印数组中的全部内容
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取图像
img=cv2.imread("my.jpg")
#调用图像线性变换--上移变换对图像进行处理
upMove=upMove(img,60)#设定上移偏量为60
#BGR转换为RGB显示格式,方便通过matplotlib进行图像显示
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
upMove=cv2.cvtColor(upMove,cv2.COLOR_BGR2RGB)
#图像与原图显示对比
titles = [ '原图像', '图像线性变换之上移变换']  
images = [img, upMove]  
for i in range(2):
    plt.subplot(1,2,i+1), plt.imshow(images[i])  
    plt.title(titles[i])  
    plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()  

《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理_第1张图片
从上图我们可以看到,图像上移变换主要作用是提升图像亮度,对于一些比较暗的图像有一定的效果,对于常规图像来说会加大图像曝光;相对于的,学习一个东西需要灵活学习,有图像上移变换,就有图像下移,那么作用就是对于一些曝光的图像进行亮度的减弱,原理和图像上移一致;对于图像上移和下移来讲,对溢出部分是不可逆的,而对于非溢出部分是可逆的,也就是可还原的!


2、图像线性变换——对比度增强变换

1)、图像对比度简介
图像对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,即指一幅图像色彩反差的大小。差异范围越大代表对比越大,差异范围越小代表对比越小,好的对比率120:1就可容易地显示生动、丰富的色彩,当对比率高达300:1时,便可支持各阶的颜色。
2)、原理
图像对比度增强就是将图像的像素值扩大的倍数,在直线中理解为增加斜率k的值,增大对比度的实质是将增大不同色彩直接的色差,使得图像能够支持显示各阶颜色
3)、计算公式
i m g 1 [ i , j ] = i m g [ i , j ] ∗ u p d a t a i m g 1 为 图 像 对 比 度 增 强 之 后 的 图 像 , i m g 是 原 始 图 像 u p d a t a 为 像 素 对 比 度 参 数 , 范 围 [ 1 , 正 无 穷 ) img1[i,j]=img[i,j]*updata\\\\ img1为图像对比度增强之后的图像,img是原始图像\\\\updata为像素对比度参数,范围[1,正无穷) img1[i,j]=img[i,j]updataimg1imgupdata[1,)
注意:当updata的范围在(0,1)时,对应的是对比度减弱变换,以下步骤只给出对比度增强原理代码,而对于对比度减弱部分,则可根据updata的范围在(0,1)对应编写
4)、图像线性变换之对比度增强变换

'''
    图像线性变换之图像对比度增强变换
'''
#定义图像对比度增强变换函数
def contrast(img,upData):#对比度增强变换的图像和对比度调节参数
    #获取图像属性包括高、宽、通道数
    h,w,c=img.shape
    #定义空白图像,用于存放图像对比度增强变换的结果,防止修改原图
    img1=np.zeros((h,w,c),dtype=img.dtype)
    #对原图进行遍历,通过图像对比度增强变换原理公式对图像进行对比度增强变换
    for i in range(h):
        for j in range(w):
            #获取原始图像个通道值并进行公式处理,然后进行防溢出处理
            b=min(255,max((img[i,j,0]*upData),0))
            g=min(255,max((img[i,j,1]*upData),0))
            r=min(255,max((img[i,j,2]*upData),0))
            #将对比度增强变换之后的值赋值给新图像
            img1[i,j]=[b,g,r]
    return img1
  • upData在[1,正无穷)时,属于对比度增强变换
  • upData在(0,1)时,属于对比度减弱变换

5)、读取图像、进行对比度增强变换,并显示结果

#导入函数库
import cv2
import numpy as np
#np.set_printoptions(threshold=np.inf)  #打印数组中的全部内容
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取图像
img=cv2.imread("my.jpg")
#调用图像线性变换--对比度增强变换对图像进行处理
contrast=contrast(img,2)#设定对比度增强参数为2
#BGR转换为RGB显示格式,方便通过matplotlib进行图像显示
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
contrast=cv2.cvtColor(contrast,cv2.COLOR_BGR2RGB)
#图像与原图显示对比
titles = [ '原图像', '图像线性变换之对比度增强变换']  
images = [img, contrast]  
for i in range(2):
    plt.subplot(1,2,i+1), plt.imshow(images[i])  
    plt.title(titles[i])  
    plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()  

《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理_第2张图片


4、图像线性变换——反色变换

1)、图像反色简介
反色是与原色叠加可以变为白色的颜色,即用白色(RGB:255,255,255)减去原色的颜色。比如说红色(RGB:255,0,0)的反色是青色(0,255,255)。色光反色一览表如下所示:
《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理_第3张图片
《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理_第4张图片
1)、原理
图像反射变换是将最高像素值255与原始像素做差得到的结果,
2)、计算公式
i m g 1 [ i , j ] = 255 − i m g [ i , j ] i m g 1 为 图 像 反 色 之 后 的 图 像 , i m g 是 原 始 图 像 img1[i,j]=255-img[i,j]\\\\ img1为图像反色之后的图像,img是原始图像 img1[i,j]=255img[i,j]img1img
3)、图像线性变换之反色变换功能函数构造

'''
    图像线性变换之图像反色变换
'''
#定义图像反色变换函数
def InvColor(img):#需要反色变换的图像
    #获取图像属性包括高、宽、通道数
    h,w,c=img.shape
    #定义空白图像,用于存放图像反色变换的结果,防止修改原图
    img1=np.zeros((h,w,c),dtype=img.dtype)
    #对原图进行遍历,通过图像反色原理公式对图像进行反色变换
    for i in range(h):
        for j in range(w):
            #获取原始图像个通道值并进行公式处理,然后进行防溢出处理
            b=max((255-img[i,j,0]),0)
            g=max((255-img[i,j,1]),0)
            r=max((255-img[i,j,2]),0)
            #将反色变换之后的值赋值给新图像
            img1[i,j]=[b,g,r]
    return img1

4)、读取图像、进行图像反色变换,并显示结果

#导入函数库
import cv2
import numpy as np
#np.set_printoptions(threshold=np.inf)  #打印数组中的全部内容
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取图像
img=cv2.imread("my.jpg")
#调用图像线性变换--反色变换对图像进行处理
InvColor=InvColor(img)
#BGR转换为RGB显示格式,方便通过matplotlib进行图像显示
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
InvColor=cv2.cvtColor(InvColor,cv2.COLOR_BGR2RGB)
#图像与原图显示对比
titles = [ '原图像', '图像线性变换之反色变换']  
images = [img, InvColor]  
for i in range(2):
    plt.subplot(1,2,i+1), plt.imshow(images[i])  
    plt.title(titles[i])  
    plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()  

《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理_第5张图片
图像反色变换通常用于医学中胸腔拍片显示和其他图像检测,对医学有重要作用!


二、图像非线性变换

在了解图像非线性变换的同时,首先应该了解非线性函数,通过非线性函数过度到图像的非线性。非线性函数即函数图像不是一条直线的函数。非线性函数包括指数函数、幂函数、对数函数、多项式函数等等基本初等函数以及他们组成的复合函数;也就是说,图像像素经过非线性变换之后的图像与原图的像素值不是成直线关系,也就是说不能通过 y = k x + b y=kx+b y=kx+b进行像素值的还原;同时,图像的非线性变换也包括如下:

  • 常规非线性变换: D b = D a ∗ D a / 255 D_b=D_a*D_a/255 Db=DaDa/255

  • 对数变换: D b = c ∗ l o g ( 1 + D a ) D_b=c*log(1+D_a) Db=clog(1+Da)

    • c:尺度比较常数
    • D a D_a Da:原始图像像素值
    • D b D_b Db:变换后的目标像素值
  • 幂指数变换(伽玛[γ]变换): D b = c ∗ D a γ D_b=c*{D_a}^γ Db=cDaγ

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

接下来,就进入以下步骤学习以上各种图像的非线性处理吧!

1、图像非线性——常规非线性变换

1)、原理
常规非线性变换就是通过非线性的特定公式进行处理,这个处理是固定的,没有参数的调节,对每一张图像都通用
2)、计算公式
i m g 1 [ i , j ] = i m g [ i , j ] ∗ i m g [ i , j ] / 255 i m g 1 为 图 像 常 规 非 线 性 变 换 之 后 的 图 像 , i m g 是 原 始 图 像 img1[i,j]=img[i,j]*img[i,j]/255\\\\ img1为图像常规非线性变换之后的图像,img是原始图像 img1[i,j]=img[i,j]img[i,j]/255img1线img
3)、图像非线性变换之常规非线性变换功能函数构造

'''
    图像非线性变换之图像常规非线性变换
'''
#定义图像常规非线性变换函数
def Nonlinearity(img):#需要常规非线性变换的图像
    #获取图像属性包括高、宽、通道数
    h,w,c=img.shape
    #定义空白图像,用于存放图像常规非线性变换的结果,防止修改原图
    img1=np.zeros((h,w,c),dtype=img.dtype)
    #对原图进行遍历,通过图像常规非线性原理公式对图像进行常规非线性变换
    for i in range(h):
        for j in range(w):
            #获取原始图像个通道值并进行公式处理,然后进行防溢出处理
            b=min(255,int(int(img[i,j,0])*int(img[i,j,0])/255))
            g=min(255,int(int(img[i,j,1])*int(img[i,j,1])/255))
            r=min(255,int(int(img[i,j,2])*int(img[i,j,2])/255))
            #将常规非线性变换之后的值赋值给新图像
            img1[i,j]=[b,g,r]
    return img1

4)、读取图像,进行图像的常规非线性变换并观察结果

#导入函数库
import cv2
import numpy as np
#np.set_printoptions(threshold=np.inf)  #打印数组中的全部内容
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取图像
img=cv2.imread("my.jpg")
#调用图像非线性变换--常规非线性变换对图像进行处理
Nonlinearity=Nonlinearity(img)
#BGR转换为RGB显示格式,方便通过matplotlib进行图像显示
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
Nonlinearity=cv2.cvtColor(Nonlinearity,cv2.COLOR_BGR2RGB)
#图像与原图显示对比
titles = [ '原图像', '图像非线性变换之常规非线性变换']  
images = [img, Nonlinearity]  
for i in range(2):
    plt.subplot(1,2,i+1), plt.imshow(images[i])  
    plt.title(titles[i])  
    plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()

《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理_第6张图片


2、图像非线性——对数变换

1)、原理
通过对数公式,对原图像的对应的像素值进行对数转换形成新的图像称为图像的对数变换,图像对数变换通常用来将暗区域的图像进行亮度提升,常用在警察对监控图像的处理。

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

2)、计算公式
i m g 1 [ i , j ] = c ∗ l o g ( 1 + i m g [ i , j ] ) i m g 1 为 图 像 对 数 变 换 之 后 的 图 像 , i m g 是 原 始 图 像 c 为 尺 度 比 较 常 数 img1[i,j]=c*log(1+img[i,j])\\\\ img1为图像对数变换之后的图像,img是原始图像\\\\c为尺度比较常数 img1[i,j]=clog(1+img[i,j])img1imgc
3)、图像非线性变换之对数变换功能函数构造

'''
    图像非线性变换之图像对数变换
'''
#定义图像对数变换函数
def logarithm(img,c1):#需要对数变换的图像和尺度比较常数
    #获取图像属性包括高、宽、通道数
    h,w,c=img.shape
    #定义空白图像,用于存放图像对数变换的结果,防止修改原图
    img1=np.zeros((h,w,c),dtype=img.dtype)
    #对原图进行遍历,通过图像对数原理公式对图像进行对数变换
    for i in range(h):
        for j in range(w):
            #获取原始图像个通道值并进行公式处理,然后进行防溢出处理
            b=min(255,int(np.log(1+img[i,j,0])*c1))
            g=min(255,int(np.log(1+img[i,j,1])*c1))
            r=min(255,int(np.log(1+img[i,j,2])*c1))
            #将对数变换之后的值赋值给新图像
            img1[i,j]=[b,g,r]
    return img1

4)、读取图像,进行非线性变换中的对数变换后观察图像

#导入函数库
import cv2
import numpy as np
#np.set_printoptions(threshold=np.inf)  #打印数组中的全部内容
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取图像
img=cv2.imread("my.jpg")
#调用图像非线性变换--对数变换对图像进行处理
logarithm=logarithm(img,20)#传递尺度比较常数20
#BGR转换为RGB显示格式,方便通过matplotlib进行图像显示
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
logarithm=cv2.cvtColor(logarithm,cv2.COLOR_BGR2RGB)
#图像与原图显示对比
titles = [ '原图像', '图像非线性变换之对数变换']  
images = [img, logarithm]  
for i in range(2):
    plt.subplot(1,2,i+1), plt.imshow(images[i])  
    plt.title(titles[i])  
    plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()

《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理_第7张图片
上图中,可能看不出来效果,应为上图中色彩分布比较均匀,各个点的像素值都差别不大,下面我们换一张夜间的图像进行对数变换,效果如下所示:
《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理_第8张图片

可以看到,对夜间的图像,通过对数变换后的效果是非常有效的,通过调节尺度比较常数,我们可得到图像暗区域的最优化结果,对夜晚摄像头捕捉非常有用。

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


3、图像非线性——伽玛变换

1)、图像伽玛变换简介
是曲线优化调整,是亮度和对比度的辅助功能,强力伽马优化模式可以对画面进行细微的明暗层次调整,控制整个画面对比度表现,再现立体美影像,此项技术的关键就在于“强力伽马曲线优化模式”,对每一帧画面都进行固定的伽马调整,画面的亮度和对比度得到大大的优化,画质也可以得到了大大的提升。专业上用的比较多,一般用不到!
2)、图像伽玛变换原理
图像伽玛变换是将原图像素通过伽玛变换公式(幂指数)进行像素值得变换,通过输入不同的尺度比较常数和伽玛值来对图像降低曝光效果,伽马变换对于图像对比度偏低,并且整体亮度值偏高(或由于相机过曝)情况下的图像增强效果明显。
3)、计算公式
i m g 1 [ i , j ] = c ∗ i m g [ i , j ] γ i m g 1 为 图 像 伽 玛 变 换 之 后 的 图 像 , i m g 是 原 始 图 像 c 为 尺 度 比 较 常 数 γ 为 对 图 像 处 理 的 伽 玛 值 img1[i,j]=c*{img[i,j]}^γ\\\\ img1为图像伽玛变换之后的图像,img是原始图像\\\\c为尺度比较常数\\\\ γ为对图像处理的伽玛值 img1[i,j]=cimg[i,j]γimg1imgcγ
其中γ的取值不同对应的意义不同,如下

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

4)、图像非线性变换之伽玛变换功能函数构造

'''
    图像非线性变换之图像伽玛变换
'''
#定义图像伽玛变换函数
def gamma(img,c1,gamma):#需要伽玛变换的图像和尺度比较常数以及伽玛值
    #获取图像属性包括高、宽、通道数
    h,w,c=img.shape
    #定义空白图像,用于存放图像伽玛变换的结果,防止修改原图
    img1=np.zeros((h,w,c),dtype=img.dtype)
    #对原图进行遍历,通过图像伽玛原理公式对图像进行伽玛变换
    for i in range(h):
        for j in range(w):
            #获取原始图像个通道值并进行公式处理,然后进行防溢出处理
            b=min(255,c1*(img[i,j,0]**gamma))
            g=min(255,c1*(img[i,j,1]**gamma))
            r=min(255,c1*(img[i,j,2]**gamma))
            #将伽玛变换之后的值赋值给新图像
            img1[i,j]=[b,g,r]
    return img1

5)、读取图像,进行图像非线性变换之伽玛变换,观察图像效果

#导入函数库
import cv2
import numpy as np
#np.set_printoptions(threshold=np.inf)  #打印数组中的全部内容
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取图像
img=cv2.imread("my.jpg")
#调用图像非线性变换--伽玛变换对图像进行处理
gamma=gamma(img,0.00000005,4)#传递尺度比较常数0.00000005和伽玛值4
#BGR转换为RGB显示格式,方便通过matplotlib进行图像显示
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
gamma=cv2.cvtColor(gamma,cv2.COLOR_BGR2RGB)
#图像与原图显示对比
titles = [ '原图像', '图像非线性变换之伽玛变换']  
images = [img, gamma]  
for i in range(2):
    plt.subplot(1,2,i+1), plt.imshow(images[i])  
    plt.title(titles[i])  
    plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()

《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理_第9张图片
同样的,由于以上图像并没有什么曝光效果,因此得到的伽玛变换效果并不是最好的,下面我们对一张摄像机拍摄的曝光的图像进行伽玛变换,然后观察效果如何,如下所示:
《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理_第10张图片
原图像的曝光效果较重,当通过伽玛变换之后,可以看出图像着重突出人物效果,将曝光的部分对比度降低。伽马变换对于图像对比度偏低,并且整体亮度值偏高情况下的图像增强效果明显。


以上就是本次博客的全部内容,遇到问题的小伙伴记得留言评论,学长看到会为大家进行解答的,这个学长不太冷!

人多时,管住嘴。话多、错多、是非多,自找麻烦;人少时,管住心。妄念、妄想、痛苦多,自找烦恼。群处守嘴,独处守心。修己以清心为要,涉世以慎言为先

陈一月的又一天编程岁月^ _ ^

你可能感兴趣的:(Opencv视觉之眼)