Pytorch加载数据dataset时PIL和cv2的异同

使用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()

在这个例子中,我的实验结果证明这两种方式得到的张量是一模一样的。

两者对比

两种读取方式的异同主要体现在以下几个方面:

  1. 速度:一般情况下,使用 OpenCV 读取图像的速度要比 PIL.Image 更快。这是因为 PIL.Image 是纯 Python 实现的库,而 OpenCV 利用了底层优化的 C++ 实现,在数据处理效率上更高。

  2. 功能:OpenCV 提供了更丰富的图像处理功能,如直方图均衡化、边缘检测、滤波等,可以对图像进行更复杂的增强和处理操作。而 PIL.Image 则提供了一些基本的图像变换方法,如旋转、裁剪、缩放等。

  3. 通道顺序:PIL.Image 默认将图像读取为 RGB 通道顺序,而 OpenCV 默认将图像读取为 BGR 通道顺序。

  4. 数据类型:PIL.Image 输出的图像张量默认为 float32 类型,而 OpenCV 输出的图像张量默认为 uint8 类型。

总的来说,两种方式的异同并不会对神经网络的训练效果产生显著影响。但是,应根据实际需求选择合适的图像读取方式,并结合具体任务适当使用数据增强操作,以提高模型的性能和泛化能力。

OpenCV和PIL的常见用法总结

OpenCV (cv2) 常见用法:
  1. 读取和保存图像:使用 cv2.imread() 方法读取图像,使用 cv2.imwrite() 方法保存图像。
import cv2

# 读取图像
img = cv2.imread('image.jpg')

# 保存图像
cv2.imwrite('new_image.jpg', img)
  1. 转换通道顺序:使用 cv2.cvtColor() 方法。
import cv2

# 将 BGR 顺序转为 RGB 顺序
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 将 RGB 顺序转为灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
  1. 调整大小和裁剪:使用 cv2.resize()numpy slicing 方法。
import cv2

# 调整图像大小
img_resized = cv2.resize(img, (width, height))

# 裁剪图像
crop_img = img[y:y+h, x:x+w]
  1. 图像增强:包括直方图均衡化、滤波等处理方法。
import cv2

# 直方图均衡化
equ = cv2.equalizeHist(gray_img)

# 滤波
blur = cv2.GaussianBlur(img, (kernel_size, kernel_size), sigmaX=sigmaX)
PIL 常见用法:
  1. 读取和保存图像:使用 PIL.Image.open() 方法读取图像,使用 Image.save() 方法保存图像。
from PIL import Image

# 读取图像
img = Image.open('image.jpg')

# 保存图像
img.save('new_image.jpg')
  1. 转换通道顺序:使用 Image.convert()Image.merge() 方法。
from PIL import Image

# 将 RGB 顺序转为灰度图
gray_img = img.convert('L')

# 将 RGBA 顺序转为 RGB 顺序
rgb_img = Image.merge('RGB', img.split()[:3])
  1. 调整大小和裁剪:使用 Image.resize()Image.crop() 方法。
from PIL import Image

# 调整图像大小
img_resized = img.resize((width, height))

# 裁剪图像
crop_img = img.crop((x, y, x+w, y+h))
  1. 图像增强:包括旋转、翻转、缩放等操作。
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 的一些常见用法。需要根据具体需求选择适合的库和方法来完成图像处理任务。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值