机器视觉学习-day02-灰度化实验
彩色图是由RGB三个通道组成,灰度图只有一个通道,也成为单通道图像,所以彩色图转换为灰度图的过程本质就是将RGB三通道合并成一个通道的过程。
灰度化实验的三种方法:最大值法、平均值法、加权平均值法
1 最大值法
最大值法就是从三个通道的值中选择最大值作为灰度后的数值,因此最大值法生成的灰度图会偏亮,适合给较暗的图像使用。
原图名1.png
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 平均法:
平均值法使用三个通道的平均值作为灰度化后的数值,对结果需要进行取整。
# 导入必要的库
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 npif __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,这个数值是根据人类生物学实验得来的。
import cv2
import numpy as np
import matplotlib.pyplot as pltif __name__ == '__main__':# 1. 图片输入path = 'image.jpg'image_np = cv2.imread(path)image_shape = image_np.shapeprint(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', # 必须:titleimage_np_gray) # 展示的图像cv2.waitKey(0) # 等待按下任意按键关闭弹窗
代码运行结果:
以上是自行所写代码,了解各个灰度化方式的运行代码流程,后续应用时使用下面的代码进行灰度化:这个函数使用的是加权平均法进行的灰度化。
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()