文章目录
- 背景
- 灰度图优势
- opencv读取灰度图
- 彩色转灰度算法
- 需求
- 方法
- 测试代码
背景
在图像处理中通常需要将图片转为灰度图
灰度图,也称为灰度图像或黑白图像,是一种只包含亮度信息而不包含颜色信息的图像。在灰度图中,每个像素的亮度级别通常用0到255之间的整数表示,其中0表示黑色,255表示白色,中间的数值表示不同级别的灰色
灰度图优势
- 简化计算:灰度图像是单通道图像,只有亮度信息,这大大减少了数据量,简化了计算过程。对于许多图像处理算法而言,处理单通道图像比处理多通道图像更快、更高效。
- 减少噪声:彩色图像中的颜色信息会引入额外的噪声,尤其是在低光环境下拍摄的照片中。将图像转换为灰度图像可以帮助去除这种由颜色引起的噪声,从而更容易检测出重要的特征。
- 便于分析:在很多计算机视觉任务中,如边缘检测、特征提取等,灰度图像可以更好地突出物体的轮廓和结构,有助于算法识别和理解图像中的关键元素。
- 节省存储空间:由于灰度图像只有一个通道,因此存储灰度图像所需的存储空间比存储相同分辨率的彩色图像要少得多。
- 提高算法鲁棒性:在某些应用场景下,如人脸识别、文字识别等,灰度图像可以提供足够的信息,同时减少由于光照条件变化导致的颜色变化对算法的影响,提高算法的鲁棒性。
- 便于应用经典算法:许多经典的图像处理算法和理论都是基于灰度图像开发的,例如直方图均衡化、形态学操作、Sobel 边缘检测等。使用灰度图像可以让这些算法更易于实现和应用。
- 降低带宽需求:在网络传输中,灰度图像的数据量较小,可以降低网络带宽的需求,这对于实时视频流等应用尤为重要。
- 便于可视化:在某些情况下,灰度图像更容易观察和分析,特别是在医学影像领域,医生通常会查看灰度图像来进行诊断
opencv读取灰度图
img_gray = cv2.imread(“test,jpg”, cv2.IMREAD_GRAYSCALE)
当使用 cv2.IMREAD_GRAYSCALE
选项读取图像时,读入的图像将自动转换为灰度图像,这意味着该图像只包含一个灰度通道而不是传统的 RGB 三通道。因此,img_gray只包含了亮度信息,而没有色彩信息
彩色转灰度算法
在OpenCV中,将彩色图像转换为灰度图像通常是通过计算彩色图像中每个像素的红、绿、蓝(RGB)三个颜色分量的加权平均值来实现的。最常用的加权方法是使用亮度(或灰度)感知的加权,因为人类对绿色的敏感度最高,对蓝色的敏感度最低
Gray=0.299×R+0.587×G+0.114×B
需求
在图像处理中,当我们将图片转换为灰度图并进行一系列处理后,得到的灰度图实际上已经丢失了原始的颜色信息。如何将灰度图直接“恢复”为彩色图
方法
- 使用灰度图像作为单通道处理,然后复制该单通道图像三次,形成一个伪彩色图像。
- 结合原始彩色图像和处理后的灰度图像,保留原始色彩信息的同时增强对比度
测试代码
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 定义直方图均衡化函数
def histogram_equalization(image):
# 应用直方图均衡化
eq = cv2.equalizeHist(image)
return eq
import numpy as np
from PIL import Image
def combine_enhanced_with_original_color2(enhanced_gray, original_color, output_path):
# 加载增强对比度的灰度图像和原始的彩色图像
#enhanced_gray = Image.open(enhanced_gray_image_path).convert('L') # 转换为灰度模式
#original_color = Image.open(original_color_image_path)
print(enhanced_gray.size,original_color.size)
# 检查两个图像尺寸是否一致,如果不一致则调整大小
#if enhanced_gray.size != original_color.size:
# original_color = original_color.resize(enhanced_gray.size)
# 将灰度图像转换为三通道图像
enhanced_rgb = np.array(enhanced_gray).astype(np.float32)
enhanced_rgb = np.stack((enhanced_rgb,) * 3, axis=-1)
# 将原始彩色图像转换为numpy数组
original_rgb = np.array(original_color).astype(np.float32)
# 合并灰度图的对比度信息与彩色图的颜色信息
# 这里简单地使用灰度图像作为亮度调整
combined_image = np.clip(original_rgb * (enhanced_rgb / 255.), 0, 255).astype(np.uint8)
# 创建一个新的PIL图像对象用于保存
combined_image_pil = Image.fromarray(combined_image)
return combined_image_pil
# 保存结果图像
#combined_image_pil.save(output_path)
# 定义结合增强后的灰度图像与原始彩色图像的函数
def combine_enhanced_with_original_color(original_color, enhanced_gray):
# 将灰度图像转换为浮点型
enhanced_gray_float = enhanced_gray.astype(np.float32)
# 归一化灰度图像到 [0, 1] 区间
enhanced_gray_normalized = cv2.normalize(enhanced_gray_float, None, 0, 10, cv2.NORM_MINMAX)
# 将灰度图像作为亮度通道与原始彩色图像结合
enhanced_color = np.zeros_like(original_color, dtype=np.float32)
enhanced_color[:, :, 0] = original_color[:, :, 0] * enhanced_gray_normalized
enhanced_color[:, :, 1] = original_color[:, :, 1] * enhanced_gray_normalized
enhanced_color[:, :, 2] = original_color[:, :, 2] * enhanced_gray_normalized
# 将结果转换回 uint8 类型
enhanced_color = np.clip(enhanced_color * 255, 0, 255).astype(np.uint8)
return enhanced_color
# 读取原始彩色图像
image_path = 'js-test01.jpg'
img_color = cv2.imread(image_path)
img_color = cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB) # 转换为 RGB 格式以正确显示颜色
# 将彩色图像转换为灰度图像
img_gray = cv2.cvtColor(img_color, cv2.COLOR_RGB2GRAY)
# 对灰度图像进行对比度增强
enhanced_img = histogram_equalization(img_gray)
# 将增强后的灰度图像作为亮度通道与原始彩色图像结合
#enhanced_color = combine_enhanced_with_original_color(img_color, img_gray)
enhanced_color = combine_enhanced_with_original_color2(img_gray,img_color,"")
# 展示图像
plt.figure(figsize=(12, 6))
plt.subplot(1, 3, 1)
plt.imshow(img_color)
plt.title('original')
plt.axis('off')
plt.subplot(1, 3, 2)
plt.imshow(img_gray)
plt.title('img_gray')
plt.axis('off')
plt.subplot(1, 3, 3)
plt.imshow(enhanced_color)
plt.title('enhanced_color')
plt.axis('off')
plt.tight_layout()
plt.show()