PIL库(Python Imaging Library)和OpenCV(cv2库)都是用于图像处理的流行工具。当你使用PIL库保存图像后,不一定非要使用PIL库加载和处理图像,你也可以使用OpenCV来加载和处理这些图像。
在一般情况下,PIL和OpenCV之间的图像转换是相对简单的,因为它们都支持常见的图像格式,如JPEG、PNG等。然而,需要注意的是,两个库可能在某些细节方面有所不同,比如像素值的范围、通道顺序等。当你在PIL和OpenCV之间切换时,你可能需要进行一些适应性的处理,以确保图像的正确显示和处理。
PIL库和OpenCV库在像素值范围和通道顺序方面存在一些差异。这些差异可能在图像处理和显示时引起问题,因此在切换库时需要注意。下面是关于这些方面的一些差异:
-
像素值范围:
- PIL库:通常将像素值限制在0到255的范围内,使用8位无符号整数(uint8)来表示像素值。
- OpenCV库:对于多数图像格式,默认将像素值限制在0到255的范围内,使用8位无符号整数表示。然而,OpenCV也支持其他像素值范围,如0到1之间的浮点数。
-
通道顺序:
- PIL库:通常使用RGB顺序来表示图像通道,即红色(R)、绿色(G)和蓝色(B)。
- OpenCV库:通常使用BGR顺序来表示图像通道,即蓝色(B)、绿色(G)和红色(R)。
当你从一个库切换到另一个库时,可能需要进行一些适应性的处理,以确保图像的正确显示和处理。以下是一些示例操作:
-
像素值范围调整:
- 如果从PIL转到OpenCV,你可能需要将像素值范围从0-255调整到合适的范围,比如0-1,这可以使用除以255的操作来实现。
-
通道顺序转换:
- 如果从PIL转到OpenCV,你可能需要对通道进行重新排序,将RGB通道顺序转换为BGR通道顺序,或者反之。
补充:
-
图像表示:
- OpenCV: 默认情况下,
cv2.imread
函数加载图像为BGR格式的NumPy数组。这意味着它会将图像的通道顺序解释为蓝色、绿色和红色。这对于处理彩色图像非常有用,但对于RGBA图像可能会导致混淆。 - PIL:
PIL.Image.open
函数加载图像为PIL图像对象。PIL图像对象具有更灵活的通道表示。您可以使用convert
方法将PIL图像转换为RGBA模式,以便处理四通道的图像。
- OpenCV: 默认情况下,
-
通道顺序:
- OpenCV: 默认情况下,
cv2.imread
加载图像的通道顺序为BGR。 - PIL:
PIL.Image.open
加载图像的通道顺序为RGB。
- OpenCV: 默认情况下,
-
加载透明通道(Alpha通道):
- OpenCV: 默认情况下,
cv2.imread
不会加载图像的透明通道,即使图像是RGBA格式。如果需要加载透明通道,需要使用cv2.IMREAD_UNCHANGED
参数。 - PIL:
PIL.Image.open
可以加载图像的所有通道,包括透明通道。
- OpenCV: 默认情况下,
-
图像类型转换:
- OpenCV: 可以使用OpenCV函数轻松进行图像操作,如调整大小、裁剪、旋转、滤波等。
- PIL: PIL也提供了一系列操作图像的方法,但在某些情况下可能需要使用NumPy来进行更复杂的图像处理。
-
兼容性:
- OpenCV: OpenCV更适用于计算机视觉和图像处理的广泛任务,包括特征提取、对象检测和图像分割等。
- PIL: PIL更专注于图像处理和图像格式转换,特别适用于图像的读取、写入、格式转换和简单处理。
在OpenCV中cv2.imread
加载的图像是一个NumPy数组,而Image.open
加载的图像是一个PIL(Python Imaging Library)图像对象,两者不完全一样。
若使用的是Image.open
,可以将PIL图像对象转换为NumPy数组,并且在PIL图像对象上没有shape
属性。取而代之的是,您可以使用size
属性来获取图像的尺寸,然后使用num_channels
来检查通道数。
#利用PIL库加载图像,并查看图像形状以及通道数
import numpy as np
from PIL import Image
# Load the image
image_path = r"C:\Users\86188\Desktop\dataset-ceshi\CECT\Train\ER\patient1\patient1_0.png"
image = Image.open(image_path)
image_np = np.array(image) # Convert PIL image to NumPy array
# Get image dimensions
print(image.size)
# Check the number of channels
num_channels = len(image.getbands())
# Determine if it's grayscale or RGB
if num_channels == 1:
print("The image is grayscale.")
elif num_channels == 3:
print("The image is RGB.")
else:
print("The image has", num_channels, "channels, which might indicate an RGBA image or some other format.")
#利用OpenCV库加载图像,并查看图像的通道数
import cv2
# Load the image
image_path = r"C:\Users\86188\Desktop\dataset-ceshi\CECT\Train\ER\patient1\patient1_0.png"
image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED) # 加载为未修改的图像 # 使用 OpenCV 的 cv2.imread(img_file_path) 加载图像
# image = cv2.imread(image_path) # 若不加cv2.IMREAD_UNCHANGED该语句,此时原图像虽然为四通道图像,但是会默认为加载三通道图像
image = cv2.resize(image, (224, 224)) # 将图像调整为指定的大小 resize
print("Image shape:", image.shape) #打印图像的形状及通道数