博客主页:真的睡不醒
系列专栏:深度学习环境搭建、环境配置问题解决、自然语言处理、语音信号处理、项目开发
每日语录:闲看花开,静待花落,冷暖自知,干净如始。
感谢大家点赞收藏⭐指正✍️
前言:本文详细介绍了如何使用python对图像进行基本的操作,包括对图像的读取、显示、修改和保存,通过Matplotlib对图像进行绘制、显示和保存,最后详细讲解了如何绘制直方图,并对直方图进行均衡化处理。欢迎大家参考和学习!
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('./work/img/rice.tif',cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('./work/img/rice.tif',cv2.IMREAD_ANYDEPTH)
plt.subplot(121)
plt.title('image 1')
plt.imshow(img,cmap='gray')
plt.subplot(122)
plt.title('image 2')
plt.imshow(img2,cmap='Reds') #
plt.show()
plt.subplot(121)
: 使用Matplotlib的subplot
函数创建一个1x2的图像窗口,并指定当前子图的索引为1。在1x2的图像窗口中,这将创建一个包含两个子图的布局,当前子图位于第1列。
plt.subplot(122)
: 设置当前子图的索引为2,即在1x2的图像窗口的第2列。
plt.imshow(img, cmap='gray')
: 并使用'gray'颜色映射(colormap)以灰度方式显示图像。同理cmap='Reds'则是红色。
''' 说明: matplotlib.pyplot.imshow默认的cmap参数 颜色映射值是:virudis,几种常见cmap参数的可视化效果如下:
第一行就是viridis类型,可以看到它是蓝绿黄渐变的一个颜色。对应灰度图就是,灰度值0对应最左边蓝色。灰度值255对应最右边黄色。 需要显示灰度图,就要将cmap值设定为gray,即:plt.imshow(img,cmap='gray')
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from PIL import Image
# 读取图片
iris = mpimg.imread(r'input_pictures/evidence.jpg') # 请据实修改路径
print(type(iris))
# 转换为numpy数组
img_array = np.array(iris)
# 将像素点矩阵所有像素点加100
new_img_array = img_array + 100
# 矩阵转换为图像
iris_new = Image.fromarray(new_img_array)
mpimg.imsave(r'output_pictures/evidence.jpg', iris_new)
# 显示图片
plt.subplot(121)
plt.imshow(iris)
plt.subplot(122)
plt.imshow(iris_new)
plt.axis('off')
plt.show()
这里在读取图像之后,得到 numpy.ndarray类型,然后将其转化为numpy数组,这个时候,我们得到的矩阵就是图像的像素点,那么我们就可以更改图像的像素点了。在更改像素点之后,要记得将矩阵转化为图像。
灰度直方图(histogram)是灰度级的函数,描述的是图像中每种灰度级像素的个数,反映图像中每种灰度出现的频率。其中,横坐标是灰度级,纵坐标是灰度级出现的频率。
对比度分析:灰度直方图可以帮助你分析图像的对比度,即不同亮度级别之间的差异程度。直方图中的峰值和谷底可以用来衡量对比度。高峰值表示高对比度,低峰值表示低对比度。
图像增强:通过灰度直方图均衡化,可以调整图像的对比度,使其更容易分辨和分析。直方图均衡化可以使图像的灰度级别更均匀,增强图像中的细节。
阈值处理:在二值图像处理中,可以使用灰度直方图来确定合适的阈值,以将图像分成前景和背景。这在图像分割和目标检测中非常有用。
检测特定特征:某些特定的特征可能在灰度直方图中产生特定的模式,例如双峰直方图表示图像中存在两个主要的亮度分布。这些特征可以用于检测或识别特定对象或情况。
直方图均衡化(Histogram Equalization)又称直方图平坦化,它的主要目标是将输入图像的像素值分布重新映射,以使其更均匀地分布在整个像素值范围内。这有助于使图像的亮度范围更广,增加对比度,并使细节更加突出。。这样,原来直方图中间的峰顶部分对比度得到增强,而两侧的谷底部分对比度降低,输出图像的直方图是一个较平的分段直方图,如果输出数据分段值较小的话,会产生粗略分类的视觉效果。
如下图:
过暗和过亮的图像 经过直方图均衡化,使得图像变得清晰。
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取彩色图像
image_path = 'work/img/屏幕截图 2023-09-14 112654.png' # 请根据实际路径修改
image = cv2.imread(image_path)
# 将彩色图像转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 计算灰度图像的直方图
gray_hist = cv2.calcHist([gray_image], [0], None, [256], [0, 256])
# 直方图均衡化
equalized_gray_image = cv2.equalizeHist(gray_image)
# 计算均衡化后图像的直方图
equalized_gray_hist = cv2.calcHist([equalized_gray_image], [0], None, [256], [0, 256])
# 可视化彩色原始图像和灰度图像
plt.figure(figsize=(12, 6))
plt.subplot(3, 2, 1)
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title('Original Color Image')
plt.subplot(3, 2, 3)
plt.imshow(gray_image, cmap='gray')
plt.title('Original Gray Image')
plt.subplot(3, 2, 4)
plt.plot(gray_hist)
plt.title('Original Gray Histogram')
# 可视化均衡化后的灰度图像
plt.subplot(3, 2, 5)
plt.imshow(equalized_gray_image, cmap='gray')
plt.title('Equalized Gray Image')
plt.subplot(3, 2, 6)
plt.plot(equalized_gray_hist)
plt.title('Equalized Gray Histogram')
plt.tight_layout()
plt.show()
这里是直接用到opencv库来处理图像和直方图,首先将图像转化为灰度图像,然后计算灰度图像的直方图,接着将直方图均衡化。
cv2.calcHist([gray_image], [0], None, [256], [0, 256])
calcHist 各个参数的含义:
images
: 这是一个图像的列表,通常是一个单通道图像(如灰度图像)。你可以传入一个图像列表,但在这里我们只有一个图像,所以我们使用[gray_image]
来表示包含一个灰度图像的列表。
channels
: 这是一个用于指定通道的索引列表。在这里,我们处理的是灰度图像,只有一个通道,因此使用[0]
来表示第一个通道(索引为0)。
mask
: 这是一个可选的遮罩图像,用于计算特定区域的直方图。如果不需要遮罩,可以传入None
。
histSize
: 这是一个整数列表,用于指定直方图的 bin 的数量。通常,它是一个整数列表,每个整数表示对应通道的 bin 的数量。在这里,我们使用[256]
表示灰度图像的 bin 的数量为256。
ranges
: 这是用于指定每个 bin 的取值范围。通常,它是一个表示最小值和最大值的整数列表。在灰度图像中,像素值范围通常是从0到255,因此我们使用[0, 256]
表示范围。
import numpy as np
import matplotlib.pyplot as plt
import imageio
# 读取彩色图像
image_path = r'work/img/屏幕截图 2023-09-14 112654.png' # 请根据实际路径修改
image = imageio.imread(image_path)
# 将彩色图像转换为灰度图像
def rgb_to_gray(rgb_image):
# 使用加权平均将RGB图像转换为灰度图像
return np.dot(rgb_image[...,:3], [0.2989, 0.5870, 0.1140]).astype(np.uint8)
gray_image = rgb_to_gray(image)
# 计算灰度图像的直方图
def calculate_histogram(image):
histogram = np.zeros(256, dtype=int)
height, width = image.shape
for i in range(height):
for j in range(width):
pixel_value = image[i, j]
histogram[pixel_value] += 1
return histogram
gray_hist = calculate_histogram(gray_image)
# 直方图均衡化
def histogram_equalization(image, histogram):
height, width = image.shape
total_pixels = height * width
cdf = np.cumsum(histogram)
equalized_image = np.zeros_like(image, dtype=np.uint8)
for i in range(256):
equalized_image[image == i] = 255 * cdf[i] // total_pixels
return equalized_image
equalized_gray_image = histogram_equalization(gray_image, gray_hist)
# 计算均衡化后图像的直方图
equalized_gray_hist = calculate_histogram(equalized_gray_image)
# 可视化彩色原始图像和灰度图像
plt.figure(figsize=(12, 6))
plt.subplot(3, 2, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Color Image')
plt.subplot(3, 2, 3)
plt.imshow(gray_image, cmap='gray')
plt.title('Original Gray Image')
plt.subplot(3, 2, 4)
plt.plot(gray_hist)
plt.title('Original Gray Histogram')
# 可视化均衡化后的灰度图像
plt.subplot(3, 2, 5)
plt.imshow(equalized_gray_image, cmap='gray')
plt.title('Equalized Gray Image')
plt.subplot(3, 2, 6)
plt.plot(equalized_gray_hist)
plt.title('Equalized Gray Histogram')
plt.tight_layout()
plt.show()