《OpenCv视觉之眼》Python图像处理四 :Opencv图像灰度处理的四种方法及原理

130
0
2021年1月26日 09时30分

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

 

前文参考:

 

《OpenCv视觉之眼》Python图像处理一 :Opencv-python的简介及Python环境搭建

《OpenCv视觉之眼》Python图像处理二 :Opencv图像读取、显示、保存基本函数原型及使用

《OpenCv视觉之眼》Python图像处理三 :Opencv图像属性、ROI区域获取及通道处理

 

上次博客我们讲解了图像属性获取图像ROI兴趣区域获取以及图像3通道的获取及原理理解,特别是对于图像3通道的原理的理解,是接下来学习OpneCV的重要基础,只有理解B\G\R三通道如何进行像素比例混合进行颜色显示,才能进行后面通过原理,书写代码,完成相关OpenCV函数功能的目的!

 

本次博客,我们将介绍OpenCV中对图像灰度化处理的函数、以及它实现的原理,通过原理,自己书写代码,完成OpenCV函数库中对于灰度函数的功能;除此之外,林君学长还将给大家介绍几种程序世界中,常用到的另外几种图像灰度处理的原理,并且编写相关Python代码进行对应理解,一起学习吧!

[Python图像处理四 ]:Opencv图像灰度处理的四种方法及原理

 

  • 一、基于OpenCV库函数的图像灰度化
    • 1、cv2.cvtColor()函数灰度处理
    • 2、cv2.cvtColor()灰度处理原理
  • 二、最大值灰度化
    • 1、最大值灰度化原理
    • 2、最大值灰度化实现
  • 三、平均值灰度化
    • 1、平均值灰度化原理
    • 2、平均值灰度化实现
  • 四、Gamma校正灰度化
    • 1、Gamma校正简介
    • 2、Gamma校正灰度化原理
    • 3、Gamma校正灰度化实现

 

图像灰度处理是OpenCV图像处理中非常重要的关键一步,例如提取图像轮廓,识别图像中需要的位置(这些后面都会讲),都会经历图像灰度处理的重要一步,下面我们会接触到图像灰度处理的各种方法,既然做图像灰度处理,首先,我们得了解图像灰度处理的基本原理,因此,首先,林君学长将带大家介绍灰度处理的基本原理。

 

  • 图像灰度处理:将彩色图像转化成为灰度图像的过程成为图像的灰度化处理。彩色图像中的每个像素的颜色有R、G、B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多(255255255)的颜色的变化范围。而灰度图像是R、G、B三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图像以使后续的图像的计算量变得少一些。灰度图像的描述与彩色图像一样仍然反映了整幅图像的整体和局部的色度和亮度等级的分布和特征。
  • 简单概括: 将3通道图像的R、G、B通道的像素从不相等设置为相等的过程,这个过程称为图像灰度处理,而一般的图像灰度处理的方法有以下四种,也就是本次博客讲解得四种,如下所示:

 

接下来,一起学习吧!

 

一、基于OpenCV库函数的图像灰度化

 

在OpenCV对图像的处理之中,提供了图像处理的灰度化函数cv2.cvtColor(),该函数包括了很多功能,对图像灰度化只是其中的一种,其他功能本次博客暂不介绍,后面会用到,本次博客只介绍该函数的图像灰度处理功能。

 

1、cv2.cvtColor()函数灰度处理

 

1)、函数原型:img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

 

  • 参数img:需要灰度处理的图像
  • 参数cv2.COLOR_BGR2GRAY:该参数为固定参数,对图像进行灰度处理固定用该参数,OpenCV读取图像通过BGR空间进行读取,因此,需要通过BGR转为GRAY进行灰度化。

 

2)、cv2.cvtColor()函数使用,使用方法

 

#导入图像处理库opencv
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取第一张图像
img=cv2.imread("my.jpg")
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#BGR转换为灰度
img= cv2.cvtColor(gray,cv2.COLOR_BGR2RGB)#BGR转换为RGB显示格式
plt.imshow(img)  
plt.title('灰度处理')    
plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()#显示图像

 

在这里插入图片描述

 

2、cv2.cvtColor()灰度处理原理

 

1)、OpenCv提供的函数进行灰度处理的原理是根据YUV的颜色空间中,Y的分量的物理意义是点的亮度,由该值反映亮度等级,根据RGB和YUV颜色空间的变化关系可建立亮度Y与R、G、B三个颜色分量的对应:Y=0.3R+0.59G+0.11B,以这个亮度值表达图像的灰度值。

 

2)、根据以上原理,我们便可以自己编写函数,通过原理实现Y亮度灰度图像处理,参考如下代码:

 

#图像灰度处理   YUV亮度灰度处理 opencv函数处理
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取第一张图像
img=cv2.imread("my.jpg")
#获取图像尺寸
h,w=img.shape[0:2]
#自定义空白单通道图像,用于存放灰度图
gray=np.zeros((h,w),dtype=img.dtype)
#对原图像进行遍历,然后分别对B\G\R按比例灰度化
for i in range(h):
    for j in range(w):
        gray[i,j]=0.11*img[i,j,0]+0.59*img[i,j,1]+0.3*img[i,j,2] #Y=0.3R+0.59G+0.11B 
gray= cv2.cvtColor(gray,cv2.COLOR_BGR2RGB)#BGR转换为RGB显示格式,方便通过matplotlib进行图像显示
plt.imshow(gray)  
plt.title('Y-亮度:灰度处理')    
plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()#显示图像

 

在这里插入图片描述

 

编写该函数其实很简单,只需要通过原理进行理解就好,接下来,林君学长带大家介绍其它几种图像灰度处理!

二、最大值灰度化

 

1、最大值灰度化原理

 

最大值灰度化原理:最大值灰度化原理其实就是以B、G、R通道中最大的像素作为整体像素,公式为:B=G=R=max([B,G,R])

 

2、最大值灰度化实现

 

#图像灰度处理   最大值灰度
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取第一张图像
img=cv2.imread("my.jpg")
#获取图像尺寸
h,w=img.shape[0:2]
#自定义空白单通道图像,用于存放灰度图
gray=np.zeros((h,w),dtype=img.dtype)
#对原图像进行遍历,然后分别对B\G\R按比例灰度化
for i in range(h):
    for j in range(w):
        gray[i,j]=max(img[i,j,0],img[i,j,1],img[i,j,2])#求3通道中最大的值
gray= cv2.cvtColor(gray,cv2.COLOR_BGR2RGB)#BGR转换为RGB显示格式,方便通过matplotlib进行图像显示
plt.imshow(gray)  
plt.title('最大值灰度')    
plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()#显示图像

 

在这里插入图片描述

 

三、平均值灰度化

 

1、平均值灰度化原理

 

平均值灰度化原理: 平均值灰度化原理就对B、G、R三通道像素求取平均值作为灰度值,公式为:gray=(B+G+R)/3

 

2、平均值灰度化实现

 

#图像灰度处理   平均灰度处理
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取第一张图像
img=cv2.imread("my.jpg")
#获取图像尺寸
h,w=img.shape[0:2]
#自定义空白单通道图像,用于存放灰度图
gray=np.zeros((h,w),dtype=img.dtype)
#对原图像进行遍历,然后分别对B\G\R按比例灰度化
for i in range(h):
    for j in range(w):
        gray[i,j]=(int(img[i,j,0])+int(img[i,j,1])+int(img[i,j,2]))/3 #求3通道像素的平均值作为灰度值
gray= cv2.cvtColor(gray,cv2.COLOR_BGR2RGB)#BGR转换为RGB显示格式,方便通过matplotlib进行图像显示
plt.imshow(gray)  
plt.title('平均值灰度化')    
plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()#显示图像

 

在这里插入图片描述

 

四、Gamma校正灰度化

 

1、Gamma校正简介

 

1)、RGB值与功率并非简单的线性关系,而是幂函数关系,这个函数的指数称为Gamma值,一般为2.2,而这个换算过程,称为Gamma校正。

 

2)、为什么显示器要Gamma校正呢?因为人眼对亮度的感知和物理功率不成正比,而是幂函数的关系,这个函数的指数通常为2.2,称为Gamma值。

 

3)、打个比方,功率为50%的灰色,人眼实际感知亮度为:捕获

 

而人眼认为的50%中灰色,实际功率为:捕获

 

所以RGB中的灰度值,为了考虑到较小的存储范围(0~255)和较平衡的亮暗部比例,所以需要进行Gamma校正,而不是直接对应功率值,因此RGB值RGB颜色值不能简单直接相加,而是必须用2.2次方换算成物理光功率后才能进行下一步计算。这一点在下面的灰度计算公式中就有所体现。

 

2、Gamma校正灰度化原理

 

1)、原理如下计算公式:

 

捕获

 

2)、注意这里的2.2次方和2.2次方根,RGB颜色值不能简单直接相加,而是必须用2.2次方换算成物理光功率。因为RGB值与功率并非简单的线性关系,而是幂函数关系,这个函数的指数称为Gamma值,一般为2.2,而这个换算过程,称为Gamma校正。

 

3、Gamma校正灰度化实现

 

#Gamma校正灰度处理
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取第一张图像
img=cv2.imread("my.jpg")
#获取图像尺寸
h,w=img.shape[0:2]
#自定义空白单通道图像,用于存放灰度图
gray=np.zeros((h,w),dtype=img.dtype)
#对原图像进行遍历,然后分别对B\G\R按比例灰度化
for i in range(h):
    for j in range(w):
        a=img[i,j,2]**(2.2)+1.5*img[i,j,1]**(2.2)+0.6*img[i,j,0]**(2.2) #分子
        b=1+1.5**(2.2)+0.6**(2.2) #分母
        gray[i,j]=pow(a/b,1.0/2.2)  #开2.2次方根
gray= cv2.cvtColor(gray,cv2.COLOR_BGR2RGB)#BGR转换为RGB显示格式,方便通过matplotlib进行图像显示
plt.imshow(gray)  
plt.title('Gamma校正灰度化')    
plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()#显示图像

 

在这里插入图片描述

2)、一般来说,Gamma校正灰度化才是最完美的灰度化,因此,是最适合人眼观察的灰度化,但在OpenCV图像处理中,用得较多的是Y亮度灰度化,至于具体原因,林君学长暂未可知,可能是Y亮度灰度化比较大众,而且已经满足实际图像处理中的需求分析了吧!

最后进行代码整合,附上一张以上灰度处理的对比图,不同的灰度处理一眼便知:

 

#整体显示
import cv2
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #显示中文
#读取第一张图像
img=cv2.imread("my.jpg")
#获取图像尺寸
h,w=img.shape[0:2]
gray1= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#BGR转换为灰度显示格式   #库函数,Y亮度
#自定义空白单通道图像,用于存放灰度图
gray2=np.zeros((h,w),dtype=img.dtype)#最大值
gray3=np.zeros((h,w),dtype=img.dtype)#平均值
gray4=np.zeros((h,w),dtype=img.dtype)#Gamma校正灰度处理
#对原图像进行遍历,然后分别对B\G\R按比例灰度化
for i in range(h):
    for j in range(w):
        gray2[i,j]=max(img[i,j,0],img[i,j,1],img[i,j,2]) #最大值
for i in range(h):
    for j in range(w):
        gray3[i,j]=(int(img[i,j,0])+int(img[i,j,1])+int(img[i,j,2]))/3 #平均值
for i in range(h):
    for j in range(w):
        a=img[i,j,2]**(2.2)+1.5*img[i,j,1]**(2.2)+0.6*img[i,j,0]**(2.2) #分子
        b=1+1.5**(2.2)+0.6**(2.2) #分母
        gray4[i,j]=pow(a/b,1.0/2.2)  #开2.2次方根  #Gamma校正灰度处理
#BGR转换为RGB显示格式,方便通过matplotlib进行图像显示
gray1= cv2.cvtColor(gray1,cv2.COLOR_BGR2RGB)
gray2= cv2.cvtColor(gray2,cv2.COLOR_BGR2RGB)
gray3= cv2.cvtColor(gray3,cv2.COLOR_BGR2RGB)
gray4= cv2.cvtColor(gray4,cv2.COLOR_BGR2RGB)
#显示图像
titles = ['cv2.cvtColor()', '最大值灰度化','平均值灰度化','Gamma校正灰度化']  #标题
images = [gray1, gray2,gray3,gray4]   #图像对比显示
for i in range(4):
    plt.subplot(1,4,i+1), plt.imshow(images[i])  
    plt.title(titles[i])    
    plt.axis('off')#关闭坐标轴  设置为on则表示开启坐标轴
plt.show()#显示图像

 

在这里插入图片描述

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

 

在青春的列车上,如果你要提前下车,请别推醒装睡的我,这样我可以沉睡到终点,假装不知道你已经离开 ——《从你的全世界路过》

 

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

发表评论

后才能评论