文章目录
一、opencv、matplotlib、pillow和pytorch读取数据的通道顺序
详细区别:
- 总结:除了pytorch得到的是nchw图片,其余方法得到的都是hwc图片;除了cv2得到的c是bgr图片,其余方法得到的c都是rgb图片;plt.imshow()既可以显示(H,W)灰色图片,也可以显示(H,W,C=3)的numpy或torch类型的RGB图片,但nhwc某批次里的图片只能一张一张显示
- opencv(imread,imshow):uint8的ndarray数据,通道顺序hwc,颜色通道BGR。
- matplotlib(imread,imshow):uint8的ndarray数据,通道顺序hwc,颜色通道RGB。
- pillow(open,show):自己的数据结构。可以np.array(image)转换成numpy数组:uint8的ndarray数据,通道顺序hwc,颜色通道RGB。可以Image.fromarray(image)将numpy数组类型转化为pillow类型。
- pythorch(torchvision.datasets、torch.utils.data.DataLoader及torchvision.io.read_image):ToTensor()到[0, 1]的torch数据,通道顺序nchw,颜色通道RGB,查看图片方法及ToPILImage。
import cv2
import matplotlib.pyplot as plt
from PIL import Image
image = cv2.imread(img_path)
cv2.imshow("image", image)
cv2.waitKey(2000)
#由bgr图片转成rgb图片:cv2.cvtColor(image, cv2.COLOR_BGR2RGB)或image[:, :, :: -1]
image = plt.imread(img_path)
plt.imshow(image)#plt.imshow(image, cmap="gray")
plt.show()#若没有显示应该是开发环境的问题
image = Image.open(img_path)
image.show()#或plt.imshow(image), plt.show()
#pytorch的nchw图片转成nhwc图片,下面train_data[0][0]代表第一张图片的数据,train_data[0][0]代表第一张图片的标签。分别plt和pillow显示
plt.imshow(train_data[0][0].permute(1, 2, 0))
plt.imshow((train_data[0][0].numpy().transpose(1,2,0)))
transforms.ToPILImage()(train_data[0][0]).show()
二、Pillow
PIL库最常用的类3:Image、ImageFilter、ImageEnhance
(1) Image类
- 返回Image实例:im=Image.open()/Image.fromarray()/Image.new(),转成数组:np.asarray(im)
- 实例常用属性:
- format(如png/jpg)
- size(宽度和高度组成的二元组,即水平和垂直方向上的像素数,像素值0为黑,255为白),width,height
- mode(图像的类型和像素的位宽,即[‘1’, ‘L’, ‘I’, ‘F’, ‘P’, ‘RGB’, ‘RGBA’, ‘CMYK’, ‘YCbCr’ ]和相应位宽,如’RGB’类型图像的每个像素占3×8位,‘P’类型图像的每个像素占8位且使用调色板映射到其他模式)
- 实例(或Image类)常用方法:
- 保存图片:save()
- 裁切图片crop((x0,y0,x1,y1)):在原始图像中以左上角为坐标原点,x0是距离左边界的距离,y0是距离上边界的距离,x1是x0+要截的宽度,y1是y0+要截的高度
- 将一张图粘贴到另一张图像上:paste(image|color,box)(其中image,box的尺寸必须一样)
- 转换新模式:convert(mode)
- 缩放和旋转图像:resize, rotate(逆时旋转给定角度值)
- 分开、合并、混合图像:split(提取RGB图像的每个颜色通道分别作为Image对象),Image.merge(mode,bands)(将各独立通道再合成一幅新的图像),Image.blend(image1,image2, alpha)(alpha是透明度,合成公式为:out=image1(1-alpha)+image2 alpha,需保证两张图像的模式和大小是一致的)
from PIL import Image im = Image.open('1.jpg') print (im. format, im.size, im.mode)#JPEG (900, 598) RGB r,b,g=im.split() r.show() im1 = Image.merge("RGB",(r,r,g)) im1.show()
- 处理图像中的每一个像素点:如im.point(lambda x :x if x>100 else 255)
- 获取图片每个通道名称的元组mode:getbands()
- 获取给定位置的像素值:pix=im.load(), pix[0, 0]或getpixel()
- list(im.getdata())依次为每一个像素点的R、G和B三个值组成的元组
im_arr = np.asarray(im) im_dat = list(im.getdata()) # im.size:177(width)x140(height), # im_arr.shape:(140, 177, 3),即(H,W,C)。len(im_arr):140,即140行;len(a[0]:177,即每行177列;len(a[0][0]):3,即每行每列的位置是每一个像素(R,G,B)三元组的值。 # len(im_dat):24780,即177x140 # im_arr[0][0],im_dat [0],im.getpixel((0,0))分别为(array([111, 60, 47], dtype=uint8), (111, 60, 47), (111, 60, 47)) # 构造出类似im_arr的array数组来生成图片:Image.fromarray(),即 np.asarray(im)的逆操作。
- getextrema() 分别获取R/G/B三个通道的最小和最大值的2元组
- 创建图像的缩略图:thumbnail(size)
- 灰度图像的直方图(像素值0~255各自的个数):histogram(),二值图像(模式为“1”)当作灰度图像(模式为“L”)处理,图像有多个通道(如模式为“RGB”),所有通道的直方图会连接起来
for i, value in enumerate(im.histogram()): print(i, value) # im为RGB三通道图片,则len为256*3=768 # r,g,b=im.split() # im.histogram()[19] == r.histogram()[19] # im.histogram()[19+256] == g.histogram()[19] # im.histogram()[19+256+256] == b.histogram()[19]
- 查找和返回帧:seek(frame),tell()
im_gif = Image.open("a.gif") im_gif.show() #当文件序列被打开时,PIL库自动指定到第0帧上 im_gif.seek(3) #在给定的文件序列中查找指定的帧 im_gif.show() print(im_gif.tell()) #返回当前帧所处位置,从0开始计算,此处返回3
(2) ImageFilter类
选择预定义滤波器:ImageFilter.BLUR/CONTOUR/DETAIL/EDGE_ENHANCE/EDGE_ENHANCE_MORE/EMBOSS/FIND_EDGES/SMOOTH/SMOOTH_MORESHARPEN,进行滤波:filter()
from PIL import ImageFilter
blu = im.filter(ImageFilter.BLUR) ##均值滤波
con = im.filter(ImageFilter.CONTOUR) ##找轮廓
edge = im.filter(ImageFilter.FIND_EDGES) ##边缘检测
(3) ImageEnchance类
先选择待增强的属性:ImageEnchance.Color/Contrast/Brightness/Sharpness,再将属性的数值增强factor倍:enchance(factor)
from PIL import ImageEnchance
col_enchan = ImageEnhance.Color(im).enhance(10) ##颜色增强10倍
col_enchan = ImageEnhance.Brightness(im).enhance(10) ##亮度增强10倍
三、OpenCV
(1)读、显示、写图片
与PIL库的区别
import cv2
im=cv2.imread(r"0.jpg") # (140, 177, 3)
cv2.namedWindow('img',cv2.WINDOW_NORMAL)
cv2.imshow('img',im)
cv2.waitKey(2000) # 2s后自动销毁
cv2.destroyAllWindows()
cv2.imwrite(r"1.png",im)
# 类似from PIL import Image,import numpy as np
im_pil = Image.open(r"0.jpg")
im_arr = np.asarray(im_pil ) # (140, 177, 3)
# cv2库得到的im和PIL库得到的im_arr都是ndarray数据,(140, 177, 3),即(H,W,C)。
# 但在C通道的三元组中,im_arr是(R,G,B),而im是(B,G,R)
# 显示图片时,分别是cv2.imshow(im)和im_pil .show()
# 采用plt库时:import matplotlib.pyplot as plt
plt.imshow(im_arr) #按(H,W,C)且C为(R,G,B)显示
# 但不能plt.imshow(im),不然就将原图RGB通道显示成了BGR通道图片,可以用plt.imshow(im[:,:,::-1])
# im与im_pil的转换,如将:cv2的im(B,G,R)转成pil-np的im_arr(R,G,B)
r, g, b = cv2.split(im)
img_pil = cv2.merge([b,g,r]), plt.imshow(img_pil)
(2) 常用操作函数
- add(加法改变颜色),addWeighted(融合获得透明效果),threshold(阈值处理),cvtColor(img,cv.COLOR_RGB2GRAY)(亮度灰度化1、2),bitwise_and/or/xor/not(像素运算1、2、3)
- 常用操作函数
(3) BGR与HSV模型
HSV模型4,
通过HSV空间对色调(Hue),饱和度(Saturation),明度(Value)进行调节5。
im_hsv = cv2.cvtColor(im,cv2.COLOR_BGR2HSV)
im_h[:,:,0] = im_hsv[:,:,0]+15 # 改变色调值会让图像整体改变颜色
im_s[:,:,1] = 0.5*colorless_hsv[:,:,1] # 减小饱和度会让图像损失鲜艳
im_v[:,:,2] = 0.5*darker_hsv[:,:,2] # 减小亮度会让图像变暗
im_bgr = cv2.cvtColor(im_h或im_s或im_v,cv2.COLOR_HSV2BGR)