彩色图是由RGB三个通道组成,灰度图只有一个通道,也成为单通道图像,所以彩色图转换为灰度图的过程本质就是将RGB三通道合并成一个通道的过程。
灰度化实验的三种方法:最大值法、平均值法、加权平均值法
1 最大值法
最大值法就是从三个通道的值中选择最大值作为灰度后的数值,因此最大值法生成的灰度图会偏亮,适合给较暗的图像使用。
原图名1.png

python
import cv2 # OpenCV库,用于图像处理
import numpy as np # NumPy库,用于数值计算和数组操作
if __name__ == '__main__':
# 1. 图片输入
path = '1.jpg' # 定义图片路径
image_np = cv2.imread(path) # 使用OpenCV读取图片
"""
cv2.imread()函数:
- 参数:图片路径
- 返回值:NumPy数组,包含图像的像素数据
- 格式:BGR顺序(不是常见的RGB顺序)
- 形状:(高度, 宽度, 通道数)
"""
image_shape = image_np.shape # 获取图像的形状(尺寸信息)
print(image_shape) # (512, 512, 3)
# 打印图像尺寸(例如(512, 512, 3)表示高512像素,宽512像素,3个颜色通道)
# 2. 创建存储灰度图的数组
# 创建一个全黑的图像数组,尺寸与原图相同,3个通道,数据类型为无符号8位整数(0-255)
image_np_gray = np.zeros((image_shape[0], image_shape[1], 3), dtype=np.uint8)
"""
np.zeros()函数:
- 参数1:数组形状 (高度, 宽度, 通道数)
- 参数2:数据类型(uint8表示0-255的整数)
- 效果:创建一个全0(黑色)的图像数组
"""
# 3. 使用最大值法进行灰度化
# 遍历全局像素
"""image_shape==(512, 512, 3)"""
for i in range(image_shape[0]): # 遍历每一行(高度方向)
for j in range(image_shape[1]): # 遍历每一列(宽度方向)
# 获取当前像素的BGR值
b, g, r = image_np[i, j] # 解包为三个变量
"""
图像像素访问:
- image_np[i, j] 返回一个包含三个值的数组 [B, G, R]
- Python的元组解包:b, g, r = [B, G, R] 分别赋值
"""
# 最大值法:取三个通道中的最大值作为灰度值
max_val = max(b, g, r) # 使用Python内置的max函数
"""
最大值法原理:
- 对于每个像素,取它的B、G、R三个通道中的最大值
- 这样得到的灰度值会使图像整体变亮
"""
# 将灰度值赋给三个通道
image_np_gray[i, j] = [max_val, max_val, max_val]
"""
为什么赋值三个相同的值?
- 显示器显示灰度图像时,需要R、G、B三个通道的值相同
- 如果只给一个通道赋值,图像会显示为单色(如红色)
"""
# 打印处理后图像的形状(应与原图相同)
print(image_np_gray.shape)
# 4.图片矫正. 图片输出
# 显示原始彩色图像
cv2.imshow('Original Image', image_np) # 第一个参数是窗口标题
# 显示处理后的灰度图像
cv2.imshow('Gray Image (Max Value Method)', image_np_gray)
"""
cv2.imshow()函数:
- 参数1:窗口标题(字符串)
- 参数2:要显示的图像数据(NumPy数组)
- 注意:OpenCV窗口会自动调整大小以适应图像
"""
cv2.waitKey(0) # 等待用户按下任意键(参数0表示无限等待)关闭弹窗
"""
cv2.waitKey()函数:
- 参数:等待时间(毫秒),0表示无限等待
- 返回值:按键的ASCII码(但这里不关心返回值)
- 功能:保持窗口显示,直到用户按键
"""
# 保存结果(可选)
cv2.imwrite('lena_gray_max_value.png', image_np_gray)
"""
cv2.imwrite()函数:
- 参数1:保存的文件名(包括扩展名)
- 参数2:要保存的图像数据
- 支持多种图像格式:PNG, JPG等
"""
代码运行后:

2 平均法:
平均值法使用三个通道的平均值作为灰度化后的数值,对结果需要进行取整。
python
# 导入必要的库
import cv2 # OpenCV库,用于图像处理(读取、显示、保存图像)
import numpy as np # NumPy库,用于高效处理数组和矩阵运算
# 程序的主入口(当直接运行此脚本时执行)
if __name__ == '__main__':
# 1. 图片输入部分
path = '1.jpg' # 指定要处理的图片路径(图片名为lena.png)
image_np = cv2.imread(path) # 使用OpenCV读取图片
"""
解释cv2.imread():
- 功能:从指定路径读取图像文件
- 返回值:一个NumPy数组,包含图像的所有像素数据
- 格式:BGR顺序(不是常见的RGB顺序)
- 形状:(高度, 宽度, 通道数)
"""
image_shape = image_np.shape # 获取图像的形状(尺寸信息)
print(f"图像尺寸: {image_shape}") # 打印图像尺寸(如(512, 512, 3)表示高512像素,宽512像素,3个颜色通道)
# 2. 创建用于存储灰度图的数组
# 创建一个全黑的图像数组,尺寸与原图相同,3个通道,数据类型为无符号8位整数(0-255)
image_np_gray = np.zeros((image_shape[0], image_shape[1], 3), dtype=np.uint8)
"""
解释np.zeros():
- 功能:创建一个指定形状的全零数组
- 参数1:(高度, 宽度, 通道数) - 这里使用原图的高度和宽度,3个通道
- 参数2:dtype=np.uint8 - 表示每个元素是0-255的整数
- 效果:创建一个全黑的图像数组
"""
# 3. 使用平均法进行灰度化处理
# 遍历图像的每一个像素
for i in range(image_shape[0]): # 遍历每一行(高度方向)
for j in range(image_shape[1]): # 遍历每一列(宽度方向)
# 获取当前像素的B、G、R值
b, g, r = image_np[i, j] # 将像素的三个通道值分别赋给b,g,r
"""
解释像素访问:
- image_np[i, j] 返回一个包含三个值的数组 [B, G, R]
- Python的元组解包:b, g, r = [B, G, R] 分别赋值
- 注意:OpenCV使用BGR顺序,不是RGB
"""
# 平均法:计算B、G、R三个值的平均值作为灰度值
avg_val = (int(b) + int(g) + int(r)) // 3 # 使用整数除法(//)避免小数
"""
平均法原理:
- 对于每个像素,计算它的B、G、R三个通道的平均值
- 公式:灰度值 = (B + G + R) / 3
- 使用整数除法(//)而不是普通除法(/):
- // 是整数除法,结果向下取整(如 100//3=33)
- 普通除法会产生小数,需要转换为整数
"""
# 将灰度值赋给三个通道(使图像显示为灰度)
image_np_gray[i, j] = [avg_val, avg_val, avg_val]
"""
为什么赋值三个相同的值?
- 显示器显示灰度图像时,需要R、G、B三个通道的值相同
- 如果只给一个通道赋值,图像会显示为单色(如红色)
- 三个通道值相同:0=黑色,255=白色,中间值=灰色
"""
# 打印处理后图像的形状(应与原图相同)
print(f"处理后图像尺寸: {image_np_gray.shape}")
# 4.图片矫正. 图片输出部分
# 显示原始彩色图像
cv2.imshow('Original Color Image', image_np) # 第一个参数是窗口标题
# 显示处理后的灰度图像
cv2.imshow('Gray Image (Average Method)', image_np_gray)
"""
解释cv2.imshow():
- 功能:在窗口中显示图像
- 参数1:窗口标题(字符串)
- 参数2:要显示的图像数据(NumPy数组)
- 注意:OpenCV窗口会自动调整大小以适应图像
"""
cv2.waitKey(0) # 等待用户按下任意键(参数0表示无限等待)
"""
解释cv2.waitKey():
- 功能:等待键盘输入
- 参数:等待时间(毫秒),0表示无限等待
- 返回值:按键的ASCII码(但这里不关心返回值)
- 作用:保持窗口显示,直到用户按键
"""
# 保存处理结果到文件
cv2.imwrite('平均灰度化.png', image_np_gray)
"""
解释cv2.imwrite():
- 功能:将图像保存到文件
- 参数1:保存的文件名(包括扩展名,如.png)
- 参数2:要保存的图像数据
- 支持多种图像格式:PNG, JPG, BMP等
"""
# 关闭所有OpenCV窗口
cv2.destroyAllWindows()
"""
解释cv2.destroyAllWindows():
- 功能:关闭所有由OpenCV创建的窗口
- 在程序结束前清理资源
"""
"""
优化修改:
import cv2
import numpy as np
if __name__ == '__main__':
# 1. 读取图片
path = 'image.jpg'
image_np = cv2.imread(path)
if image_np is None:
print("错误:无法读取图片,请检查路径")
exit()
print(f"原始图像尺寸: {image_np.shape}")
# 2. 使用向量化操作进行灰度化(平均法)
# 更高效的方法:直接计算三个通道的平均值
gray_vals = np.mean(image_np, axis=2, dtype=np.uint8)
# 3. 创建三通道灰度图像
image_np_gray = np.stack([gray_vals] * 3, axis=-1)
print(f"处理后图像尺寸: {image_np_gray.shape}")
# 4.图片矫正. 显示和保存结果
cv2.imshow('Original Color Image', image_np)
cv2.imshow('Gray Image (Average Method)', image_np_gray)
cv2.waitKey(0)
cv2.imwrite('平均灰度化.png', image_np_gray)
cv2.destroyAllWindows()
"""

3 加权平均值法
使用RGB的加权平均数作为灰度化的数值,RGB的权重系数分别为0.299,0.587,0.114,这个数值是根据人类生物学实验得来的。
python
import cv2
import numpy as np
import matplotlib.pyplot as plt
if __name__ == '__main__':
# 1. 图片输入
path = 'image.jpg'
image_np = cv2.imread(path)
image_shape = image_np.shape
print(image_shape) # (512, 512, 3)
# print(image_np)
# 灰度化处理
# 初始化灰度图像存储
# 2. 三通道图 + 灰度化
# 创建一个纯黑图(B,G,R为0),分辨率相同,用于后续存储灰度后的数据
image_np_gray = np.zeros((image_shape[0], image_shape[1], 3), dtype=np.uint8)
print(image_np_gray.shape)
# 数据拷贝
image_np_gray = image_np.copy()
# print(image_np_gray)
# 三个权重
wr = 0.299 # 红色权重
wg = 0.587 # 绿色权重
wb = 0.114 # 蓝色权重
# 遍历全局像素
for i in range(image_shape[0]):
for j in range(image_shape[1]):
# print(i,j)
# 加权平均法计算灰度值
avg = image_np[i, j][2] * wr + image_np[i, j][1] * wg + image_np[i, j][0] * wb
# 通道顺序:
# image_np[i, j][0]:蓝色通道(B)
# image_np[i, j][1]:绿色通道(G)
# image_np[i, j][2]:红色通道(R)
# print(avg)
avg = int(avg) # 取整/浮点数改整数
# print(avg)
# 存储到image_np_gray中
image_np_gray[i, j] = avg # 三通道赋相同值
print(image_np_gray.shape)
print(image_np_gray) # 如果BGR三通道的数值相同,表示灰度,但真正的灰度只需要一个通道
# 4.图片矫正. 图片输出
# plt.imshow(image_np_gray)
# plt.title('image_np_gray')
# plt.axis('off')
# plt.show()
# 后续彩图可以直接使用OpenCV展示,CV展示图片会收到系统缩放的影响
cv2.imshow('image_np_gray', # 必须:title
image_np_gray) # 展示的图像
cv2.waitKey(0) # 等待按下任意按键关闭弹窗
代码运行结果:
以上是自行所写代码,了解各个灰度化方式的运行代码流程,后续应用时使用下面的代码进行灰度化:这个函数使用的是加权平均法进行的灰度化。
python
import cv2
# 读取彩色图像
image = cv2.imread('image.jpg') # 替换为你的图像路径
# 检查图像是否正确加载
if image is None:
print("错误: 无法读取图像,请检查文件路径")
exit()
# 将BGR图像转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 显示原始图像和灰度图像
cv2.imshow('Original Color Image', image)
cv2.imshow('Grayscale Image', gray_image)
# 保存灰度图像
cv2.imwrite('gray_image.jpg', gray_image)
# 等待按键后关闭所有窗口
cv2.waitKey(0)
cv2.destroyAllWindows()