使用cv2读取并加载数据
使用 OpenCV (cv2) 库来读取图像文件,相对于 PIL.Image,OpenCV 具有更快的读取速度和更强的图像处理功能,尤其适用于图像预处理、增强等操作。
下面是一个使用 OpenCV 读取图像并转换为 PyTorch 张量的例子:
import cv2
import torch
class CustomDataset(torch.utils.data.Dataset):
def __init__(self, data_dir, transforms=None):
self.data_dir = data_dir
self.transforms = transforms
def __getitem__(self, index):
img_name = 'image{}.jpg'.format(index)
img_path = os.path.join(self.data_dir, img_name)
img = cv2.imread(img_path) # 使用 OpenCV 读取图像
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转换通道顺序为 RGB
if self.transforms is not None:
img = self.transforms(img)
return img
def __len__(self):
return len(os.listdir(self.data_dir))
在上述代码中,我们首先通过 cv2.imread()
方法读取指定路径下的图像文件,并将图像像素值按 BGR 顺序存储在 numpy 数组中。接着,使用 cv2.cvtColor()
方法将通道顺序转换为 PyTorch 所需的 RGB 顺序。最后,根据需要应用数据增强操作,并返回转换后的张量对象。
需要注意的是,由于 OpenCV 和 PIL.Image 中的通道顺序不同,因此在转换通道顺序时需要使用 cv2.cvtColor()
方法进行转换。
使用两种方式读取后转换成的tensor是否一致
下面是将两种方式得到的图像分别转换为张量的示例代码,如果它们是一致的,那么断言就会通过,否则会抛出异常。
import cv2
from PIL import Image
import torch
import torchvision.transforms as transforms
# 使用 OpenCV 读取并转换图像
img_cv2 = cv2.imread('image.jpg')
img_cv2 = cv2.cvtColor(img_cv2, cv2.COLOR_BGR2RGB)
# 使用 PIL 读取图像
img_pil = Image.open('image.jpg')
assert (img_cv2 == img_pil).all()
##########################################################
# 将两种方式的图像都转换为张量
transform = transforms.Compose([
transforms.ToTensor(),
])
tensor_cv2 = transform(img_cv2)
tensor_pil = transform(img_pil)
# 比较两种方式得到的张量是否一致
assert (tensor_cv2 == tensor_pil).all()
在这个例子中,我的实验结果证明这两种方式得到的张量是一模一样的。
两者对比
两种读取方式的异同主要体现在以下几个方面:
-
速度:一般情况下,使用 OpenCV 读取图像的速度要比 PIL.Image 更快。这是因为 PIL.Image 是纯 Python 实现的库,而 OpenCV 利用了底层优化的 C++ 实现,在数据处理效率上更高。
-
功能:OpenCV 提供了更丰富的图像处理功能,如直方图均衡化、边缘检测、滤波等,可以对图像进行更复杂的增强和处理操作。而 PIL.Image 则提供了一些基本的图像变换方法,如旋转、裁剪、缩放等。
-
通道顺序:PIL.Image 默认将图像读取为 RGB 通道顺序,而 OpenCV 默认将图像读取为 BGR 通道顺序。
-
数据类型:PIL.Image 输出的图像张量默认为 float32 类型,而 OpenCV 输出的图像张量默认为 uint8 类型。
总的来说,两种方式的异同并不会对神经网络的训练效果产生显著影响。但是,应根据实际需求选择合适的图像读取方式,并结合具体任务适当使用数据增强操作,以提高模型的性能和泛化能力。
OpenCV和PIL的常见用法总结
OpenCV (cv2) 常见用法:
- 读取和保存图像:使用
cv2.imread()
方法读取图像,使用cv2.imwrite()
方法保存图像。
import cv2
# 读取图像
img = cv2.imread('image.jpg')
# 保存图像
cv2.imwrite('new_image.jpg', img)
- 转换通道顺序:使用
cv2.cvtColor()
方法。
import cv2
# 将 BGR 顺序转为 RGB 顺序
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 将 RGB 顺序转为灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
- 调整大小和裁剪:使用
cv2.resize()
和numpy slicing
方法。
import cv2
# 调整图像大小
img_resized = cv2.resize(img, (width, height))
# 裁剪图像
crop_img = img[y:y+h, x:x+w]
- 图像增强:包括直方图均衡化、滤波等处理方法。
import cv2
# 直方图均衡化
equ = cv2.equalizeHist(gray_img)
# 滤波
blur = cv2.GaussianBlur(img, (kernel_size, kernel_size), sigmaX=sigmaX)
PIL 常见用法:
- 读取和保存图像:使用
PIL.Image.open()
方法读取图像,使用Image.save()
方法保存图像。
from PIL import Image
# 读取图像
img = Image.open('image.jpg')
# 保存图像
img.save('new_image.jpg')
- 转换通道顺序:使用
Image.convert()
和Image.merge()
方法。
from PIL import Image
# 将 RGB 顺序转为灰度图
gray_img = img.convert('L')
# 将 RGBA 顺序转为 RGB 顺序
rgb_img = Image.merge('RGB', img.split()[:3])
- 调整大小和裁剪:使用
Image.resize()
和Image.crop()
方法。
from PIL import Image
# 调整图像大小
img_resized = img.resize((width, height))
# 裁剪图像
crop_img = img.crop((x, y, x+w, y+h))
- 图像增强:包括旋转、翻转、缩放等操作。
from PIL import Image
# 旋转图像
rotated_img = img.rotate(angle)
# 水平翻转
flipped_img = img.transpose(Image.FLIP_LEFT_RIGHT)
# 垂直翻转
flipped_img = img.transpose(Image.FLIP_TOP_BOTTOM)
以上是 OpenCV(cv2) 和 PIL 的一些常见用法。需要根据具体需求选择适合的库和方法来完成图像处理任务。