参考资料
Python OpenCV中的numpy与图像类型转换
解决ndarray的类型错误
Python OpenCV格式和PIL.Image格式 互转
python模块 opencv-python与PIL.Image图像常用方法与相互转换
OpenCV读取图片与PIL读取图片的差别
python中PIL.Image,OpenCV,Numpy图像格式相互转换
PIL.Image和np.ndarray图片与Tensor之间的转换
Numpy与Opencv格式互转 参照资料1
Python OpenCV存储图像使用的是Numpy存储,所以可以将Numpy当做图像类型操作,操作之前还需进行类型转换,转换到int8类型
对Opencv存储的图像格式进行验证
1 2 3 4 5 6 7 8 9 10 11 """ numpy与Opencv图像类型的转换 > Python OpenCV存储图像使用的是Numpy存储,所以可以将Numpy当做图像类型操作,操作之前还需进行类型转换,转换到int8类型 """ import cv2import numpy as npfrom PIL import Imageimg = cv2.imread('./Messi.jpg' ) print ("shape:" + str (img.shape))print (type (img))
1 2 shape:(500, 500, 3) <class 'numpy.ndarray'>
存储类型为numpy.ndarray,这是否表明numpy与Opencv可以直接互操作呢?答案是否定的。因为图像存放时,每个像素值都是非负的,并且取值范围受限于存储位数的限制,所以将numpy.ndarray存储为图像格式,需要先将其进行类型转换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 array = np.ones([20 , 30 ]) print ("shape:" + str (array.shape))print (type (array)) """ 类型转换时需注意,我参照博客转成int8类型,可以写入,但是单通道转多通道会出错 Assertion failed) VScn::contains(scn) && VDcn::contains(dcn) && VDepth::contains(depth) in function 'CvtHelper' 参照github是类型错误导致的 """ array = np.uint8(array) print ("shape:" + str (array.shape))cv2.imwrite('test.jpg' , array) array = cv2.cvtColor(array, cv2.COLOR_GRAY2BGR) print ("shape:" + str (array.shape))cv2.imwrite('test2.jpg' , array)
1 2 3 4 shape:(20, 30) <class 'numpy.ndarray'> shape:(20, 30) shape:(20, 30, 3)
正如注释所写,类型转换时,要注意,我参照资料1 转为int8,在通道转换时出现了错误Assertion failed) VScn::contains(scn) && VDcn::contains(dcn) && VDepth::contains(depth) in function ‘CvtHelper’ ,参照资料2 进行解决。
IPL.Image与Opencv相互转换 先复习一下Opencv与IPL.Image的读,写,显示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 """ Opencv 图像的读,写,显示 PIL.Image的读,写,显示 """ img = cv2.imread('Messi.jpg' ) cv2.imwrite('Messi2.jpg' , img) cv2.imshow('Messi' , img) img = Image.open ('Messi.jpg' ) img.save('Messi3.jpg' ) img.show()
Image.open()读取的通道顺序是RGB,cv2.imread()读取的通道顺序为BGR。 Image.open()函数只是保持了图像被读取的状态,但是图像的真实数据并未被读取,因此如果对需要操作图像每个元素,如输出某个像素的RGB值等,需要执行对象的load()方法读取数据 PIL.Image.save()直接保存RGB的图片 cv2.imwirte()保存图片的时候相当于做了BGR2RGB再去保存
OpenCV转换成PIL.Image格式
1 2 3 4 5 6 import cv2 from PIL import Image import numpy img = cv2.imread("Messi.jpg" ) cv2.imshow("OpenCV" ,img) Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))
PIL.Image转换成OpenCV格式:
1 2 3 4 5 import cv2 from PIL import Image import numpy image = Image.open ("Messi.jpg" ) img = cv2.cvtColor(numpy.asarray(image),cv2.COLOR_RGB2BGR)
PIL.Image与Numpy格式的相互转换 相当于 Opencv与PIL.Image的相互转换少了通道的变换。
1 2 3 4 5 import cv2from PIL import Image import numpy array = np.ones(100 , 200 ) Image.fromarray(array)
1 2 3 4 5 import cv2from PIL import Imageimport numpy image = Image.open ("Messi.jpg" ) array = numpy.asarray(image)
补充 参考资料6
list与tuple转换 1 2 3 a = [1 , 2 , 3 ] b = tuple (a) c = list (b)
list,tuple,ndarray转换 1 2 3 a = [1 , 2 , 3 ] arr = np.array(a) b = tuple (arr)
1 2 3 a = (1 , 2 , 3 ) arr = np.arr(a) b = list (arr)
torch的tensor与numpy转换 1 2 3 4 5 array = a.numpy() torch.from_numpy(array)
tensor与PIL image转换 pytorch官方提供了torchvision.transforms
包,可以用transforms
来实现tensor 与PIL image的转换
ToTensor把一个取值范围是[0,255]的PIL.Image或者shape为(H,W,C)的numpy.ndarray,转换成形状为[C,H,W],取值范围是[0,1.0]的torch.FloadTensor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import torchfrom torchvision import transformsfrom PIL import Imageimport cv2transform1 = transforms.Compose([ pass , transforms.ToTensor(), ] ) img_PIL = Image.open ('test.jpg' ).convert('RGB' ) img_PIL_tensor = transform1(img_PIL) print (type (img_PIL))print (type (img_PIL_tensor))new_img_PIL = transforms.ToPILImage()(img_PIL_Tensor).convert('RGB' ) transform2 = transforms.Compose([ pass , transforms.ToTensor(), ] ) img_Opencv = cv2.imread('test' .jpg) img_Opencv_tensor = transform2(img_Opencv)