最近在研究深度学习视觉相关的东西,经常需要写python代码搭建深度学习模型。比如写CNN模型相关代码时,我们需要借助python图像库来读取图像并进行一系列的图像处理工作。我最常用的图像库当然是opencv,很强大很好用,但是opencv也有一些坑,不注意的话也会搞出大麻烦。近期我也在看一些别人写的代码,因为个人习惯不一样,他们在做深度学习时用于图片读取的图像库各不相同,从opencv到PIL再到skimage等等各种库都有,有些库读进来的图片存储方式也不太一样,如果不好好总结这些主流图像读写库特点的话,以后看代码写代码都会遇坑无数。这篇文章就总结了以下主流Python图像库的一些基本使用方法和需要注意的地方:
1.opencv
2.PIL(pillow)
3.matplotlib.image
4.scipy.misc
5.skimage
opencv: cv2.imread
opencv作为我最常用的图像处理库,当然第一个介绍,并且介绍得比较全面。毋庸置疑,opencv是今天介绍得所有图像库中最全面也最强大的库,如果我们只想掌握一个图像库,我觉得opencv库肯定是最适合不过了。
图片读取操作
import cv2 import numpy as np #读入图片:默认彩色图,cv2.IMREAD_GRAYSCALE灰度图,cv2.IMREAD_UNCHANGED包含alpha通道 img = cv2.imread('1.jpg') cv2.imshow('src',img) print(img.shape) # (h,w,c) print(img.size) # 像素总数目 print(img.dtype) print(img) cv2.waitKey()
值得注意的是,opencv读进来的图片已经是一个numpy矩阵了,彩色图片维度是(高度,宽度,通道数)。数据类型是uint8。
#gray = cv2.imread('1.jpg',cv2.IMREAD_GRAYSCALE) #灰度图 #cv2.imshow('gray',gray) #也可以这么写,先读入彩色图,再转灰度图 src = cv2.imread('1.jpg') gray = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY) cv2.imshow('gray',gray) print(gray.shape) print(gray.size) print(gray) cv2.waitKey()
上面提到了两种获取灰度图的方式,读进来的灰度图的矩阵格式是(高度,宽度)。
#注意,计算图片路径是错的,Opencv也不会提醒你,但print img时得到的结果是None img2 = cv2.imread('2.jpg') print(img2)
#如何解决“读到的图片不存在的问题”? #加入判断语句,如果为空,做异常处理 img2 = cv2.imread('2.jpg') if img2 == None: print('fail to load image!')
图片矩阵变换
opencv读入图片的矩阵格式是:(height,width,channels)。而在深度学习中,因为要对不同通道应用卷积,所以会采取另一种方式:(channels,height,width)。为了应对该要求,我们可以这么做
#注意到,opencv读入的图片的彩色图是一个channel last的三维矩阵(h,w,c),即(高度,宽度,通道) #有时候在深度学习中用到的的图片矩阵形式可能是channel first,那我们可以这样转一下 print(img.shape) img = img.transpose(2,0,1) print(img.shape)
在深度学习搭建CNN时,往往要做相应的图像数据处理,比如图像要扩展维度,比如扩展成(batch_size,channels,height,width)。
对于这种要求,我们可以这么做。
#有时候还要扩展维度,比如有时候我们需要预测单张图片,要在要加一列做图片的个数,可以这么做 img = np.expand_dims(img, axis=0) print(img.shape)
上面提到的是预测阶段时预测单张图片的扩展维度的操作,如果是训练阶段,构建batch,即得到这种形式:(batch_size,channels,height,width)。我一般喜欢这么做
data_list = [] loop: im = cv2.imread('xxx.png') data_list.append(im) data_arr = np.array(data_list)
这样子就能构造成我们想要的形式了。
图片归一化
#因为opencv读入的图片矩阵数值是0到255,有时我们需要对其进行归一化为0~1 img3 = cv2.imread('1.jpg') img3 = img3.astype("float") / 255.0 #注意需要先转化数据类型为float print(img3.dtype) print(img3)
存储图片
#存储图片 cv2.imwrite('test1.jpg',img3) #得到的是全黑的图片,因为我们把它归一化了 #所以要得到可视化的图,需要先*255还原 img3 = img3 * 255 cv2.imwrite('test2.jpg',img3) #这样就可以看到彩色原图了
opencv大坑之BGR
opencv对于读进来的图片的通道排列是BGR,而不是主流的RGB!谨记!
#opencv读入的矩阵是BGR,如果想转为RGB,可以这么转 img4 = cv2.imread('1.jpg') img4 = cv2.cvtColor(img4,cv2.COLOR_BGR2RGB)
访问像素
#访问像素 print(img4[10,10]) #3channels print(gray[10,10]) #1channel img4[10,10] = [255,255,255] gray[10,10] = 255 print(img4[10,10]) #3channels print(gray[10,10]) #1channel
ROI操作
#roi操作 roi = img4[200:550,100:450,:] cv2.imshow('roi',roi) cv2.waitKey()
通道操作
#分离通道 img5 = cv2.imread('1.jpg') b,g,r = cv2.split(img5) #合并通道 img5 = cv2.merge((b,g,r)) #也可以不拆分 img5[:,:,2] = 0 #将红色通道值全部设0
PIL:PIL.Image.open
图片读取
from PIL import Image import numpy as np
PIL即Python Imaging Library,也即为我们所称的Pillow,是一个很流行的图像库,它比opencv更为轻巧,正因如此,它深受大众的喜爱。
图像读写
PIL读进来的图像是一个对象,而不是我们所熟知的numpy 矩阵。
img = Image.open('1.jpg') print(img.format) print(img.size) #注意,省略了通道 (w,h) print(img.mode) #L为灰度图,RGB为真彩色,RGBA为加了透明通道 img.show() # 显示图片
灰度图的获取
gray = Image.open('1.jpg').convert('L') gray.show()
#读取不到图片会抛出异常IOError,我们可以捕捉它,做异常处理 try: img2 = Image.open('2.jpg') except IOError: print('fail to load image!')
#pillow读进来的图片不是矩阵,我们将图片转矩阵,channel last arr = np.array(img3) print(arr.shape) print(arr.dtype) print(arr)
灰度图的转化与彩图转化一样
arr_gray = np.array(gray) print(arr_gray.shape) print(arr_gray.dtype) print(arr_gray)
存储图片
#矩阵再转为图像 new_im = Image.fromarray(arr) new_im.save('3.png')
图像操作
#分离合并通道 r, g, b = img.split() img = Image.merge("RGB", (b, g, r))
img = img.copy() #复制图像
ROI获取
img3 = Image.open('1.jpg') roi = img3.crop((0,0,300,300)) #(左上x,左上y,右下x,右下y)坐标 roi.show()
matplotlib:matplotlib.image.imread
matplotlib是一个科学绘图神器,用的人非常多。
import matplotlib.pyplot as plt import numpy as np
image = plt.imread('1.jpg') plt.imshow(image) plt.show()
#也可以关闭显示x,y轴上的数字 image = plt.imread('1.jpg') plt.imshow(image) plt.axis('off') plt.show()
#plt.imread读入的就是一个矩阵,跟opencv一样,但彩图读进的是RGB,与opencv有区别 print(image.shape) # (h,w,c) print(image.size) print(image.dtype) print(image)
im_r = image[:,:,0] #红色通道 plt.imshow(im_r) plt.show() #此时会发现显示的是热量图,不是我们预想的灰度图,可以添加 cmap 参数解决 plt.imshow(im_r,cmap='Greys_r') plt.show()
#与opencv结合使用 import cv2 im2 = cv2.imread('1.jpg') plt.imshow(im2) plt.axis('off') plt.show() #发现图像颜色怪怪的,原因当然是我们前面提到的RGB顺序不同的原因啦,转一下就好 im2 = cv2.cvtColor(im2,cv2.COLOR_BGR2RGB) plt.imshow(im2) plt.axis('off') plt.show() #所以无论用什么库读进图片,只要把图片改为矩阵,那么matplotlib就可以处理了
#再试一试pillow和matplotlib结合 from PIL import Image im3 = Image.open('1.jpg') im3 = np.array(im3) plt.figure(1) plt.imshow(im3) plt.axis('off') #存储图像,注意,必须在show之前savefig,否则存储的图片一片空白 plt.savefig('timo.jpg') plt.show()
#最后以一个综合例子总结matplotlib最基本的图片显示技巧吧 im_lol1 = plt.imread('lol.jpg') im_lol2 = plt.imread('1.jpg') figure = plt.figure(figsize=(20,10)) # 调整显示图片的大小 ''' figsize参数:指定绘图对象的宽度和高度,单位为英寸;dpi参数指定绘图对象的分辨率, 即每英寸多少个像素,缺省值为80。因此本例中所创建的图表窗口的宽度为8*80 = 640像素 ''' plt.axis("off")#不显示刻度 ax = figure.add_subplot(121) # 图片以1行2列的形式显示 plt.axis('off') ax.imshow(im_lol1) #第一张图 ax.set_title('lol image 1')#给图片加titile ax = figure.add_subplot(122) plt.axis('off') ax.imshow(im_lol2) ax.set_title('lol image 2')#给图片加titile plt.savefig('twp.jpg') plt.show()
scipy.misc:scipy.misc.imread
from scipy import misc import matplotlib.pyplot as plt
im = misc.imread('1.jpg') print(im.dtype) print(im.size) print(im.shape) misc.imsave('misc1.png',im) plt.imshow(im) plt.show() print(im)
可以看到,有warining,提示我们imread和imsave在后来的版本将会被弃用,叫我们使用imageio.imread和imageio.imwrite。
我们根据她的提示,使用imageio模块进行图片读写,warning也就没有了。
import imageio im2 = imageio.imread('1.jpg') print(im2.dtype) print(im2.size) print(im2.shape) plt.imshow(im) plt.show() print(im2) imageio.imsave('imageio.png',im2)
skimage:skimage.io.imread
from skimage import io im = io.imread('1.jpg') print(im.shape) # numpy矩阵,(h,w,c) print(im.dtype) print(im.size) io.imshow(im) io.imsave('sk.png',im) print(im)
图像也是以numpy array形式读入。
灰度图的获取方式:
im2 = io.imread('1.jpg',as_grey=True) #读入灰度图 print(im2.dtype) print(im2.size) print(im2.shape) io.imshow(im2) io.imsave('sk_gray.png',im2) io.show() print(im2)
可以看到,灰度图像的矩阵的值被归一化了,注意注意!
也可以以这种方式获得灰度图:
from skimage import color im3 = io.imread('1.jpg') im3 = color.rgb2grey(im3) print(im3.dtype) print(im3.size) print(im3.shape) io.imshow(im3) io.show() ''' skimage.color.rgb2grey(rgb) skimage.color.rgb2hsv(rgb) skimage.color.rgb2lab(rgb) skimage.color.gray2rgb(image) skimage.color.hsv2rgb(hsv) skimage.color.lab2rgb(lab) '''
总结
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍Java读写文件方法总结(推荐),包括了Java读写文件方法总结(推荐)的使用技巧和注意事项,需要的朋友参考一下 Java的读写文件方法在工作中相信有很多的用处的,本人在之前包括现在都在使用Java的读写文件方法来处理数据方面的输入输出,确实很方便。奈何我的记性实在是叫人着急,很多时候既然都会想不起来怎么写了,不过我的Java代码量也实在是少的可怜,所以应该多多练习。这里做一个总结,
本文向大家介绍Python读写文件方法总结,包括了Python读写文件方法总结的使用技巧和注意事项,需要的朋友参考一下 本文实例总结了Python读写文件方法。分享给大家供大家参考。具体分析如下: 1.open 使用open打开文件后一定要记得调用文件对象的close()方法。比如可以用try/finally语句来确保最后能关闭文件。 注:不能把open语句放在try块里,因为当打开文件出现异常时
本文向大家介绍使用Nibabel库对nii格式图像的读写操作,包括了使用Nibabel库对nii格式图像的读写操作的使用技巧和注意事项,需要的朋友参考一下 因为后期主要的研究方向是医学图像处理,而现有手头的大部分数据都是nii格式或者是hdr,img格式的数据,所以首先第一步我们需要解决图像的读写问题。 其实使用OpenCV也可以方便的进行图像读取,但是这里暂时只学习Nibabel这个库,后面有时
我们目前正在一个网站上使用全屏图像幻灯片,初始测试非常有效,下面的代码显示了它的工作原理: 我们要做的是从CSM动态地写入图像。我现在做的是列出一个简单的列表,如下所示: 我们需要做的是获取此图像列表并将其注入到$.vegas backgrounds:[]函数列表中。。。 我已经尝试了下面的代码,可以得到图像列表,但我不确定您将如何将其放入$. vegas函数: 因此,这里的职位。非常感谢您的帮助
本文向大家介绍Bootstrap Img 图片样式(推荐),包括了Bootstrap Img 图片样式(推荐)的使用技巧和注意事项,需要的朋友参考一下 Bootstrap提供了四种用于<img>类的样式,分别是: .img-rounded:圆角 (IE8 不支持),添加 border-radius:6px 来获得图片圆角; .img-circle:圆形 (IE8 不支持),添加 border-r
问题内容: 我尝试了以下代码来完成读取和写入tiff图像的任务: 但是,当我运行代码时,出现以下错误消息: 知道如何解决这个问题吗? 问题答案: 读取TIFF并输出BMP的最简单方法是使用ImageIO类: 要使此功能正常工作,您唯一需要做的另一件事是确保已将JAI ImageIO JAR添加到类路径中,因为如果没有此库中的插件,JRE不会处理BMP和TIFF。 如果由于某种原因不能使用JAI I