作为初学者,关注和学习图像处理的python+opencv解决方案。
梳理了一系列与读入和显示图像有关的程序,进行了对比试验,并做了简单的小结。
一、实验
1.用opencv进行彩色和灰度image读写,打印彩色img的信息;
2.1用matplotlib进行彩色和灰度image读写,打印彩色img的信息;
2.2用matplotlib显示灰度图;
3.opencv的BGR与matplotlib的RGB频道切换;
4.pillow和matplotlib结合显示和保存图像;
5.较为全面的matplotlib最基本的图片显示技巧;
#无论用什么库读进图片,只要把图片改为矩阵,matplotlib就可以处理
6.使用scipy.misc:scipy.misc.imread;
7.使用skimage:skimage.io.imread。
二、总结
(1)除了opencv读入的彩色图片以BGR顺序存储外,其他所有图像库读入彩色图片都以RGB存储。
(2)除了PIL读入的图片是img类之外,其他库读进来的图片都是以numpy 矩阵。
三、代码和结果
代码参考了《Python各类图像库的图片读写方式总结》(http://www.cnblogs.com/skyfsm/p/8276501.html),做了一些增删和改进。
'''
1.用opencv进行彩色和灰度image读写,打印彩色img的信息
'''
import cv2
import numpy as np
# cv2直接读入和显示彩色图像:
img = cv2.imread('house.jpg') # 读入图像后的类型为numpy.ndarray,BGR频道。
cv2.imshow('ColorImgShowWindow',img) # 注意是BGR频道,如果用plt.imread则显示色彩异常
print(img.shape) # (h,w,c)。
print(img.size) # 像素总数目。
print(img.dtype) # 数据类型。
print(type(img))
print(img)
# cv2直接读入和显示灰度图像:
gray1 = cv2.imread('house.jpg',cv2.IMREAD_GRAYSCALE) # 默认彩色图,cv2.IMREAD_UNCHANGED包含alpha频道。
cv2.imshow('DirecGrayImg',gray1)
# 先读入彩色图,再转灰度图:
img2 = cv2.imread('house.jpg')
gray2 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
cv2.imshow('ConvertColor2GrayImg',gray2)
print(gray2.shape)
print(gray2.size)
print(gray2)
# 如果要读的图片不存在,加入判断语句,做异常处理:
img2 = cv2.imread('2.jpg')
if img2 == None:
print('fail to load image!')
cv2.waitKey() # 只有执行这一句,cv2才能显示图像
# cv2.waitKey()函数指定当前的窗口显示要持续的时间的毫秒数,
# 0表示一直显示直至按下键或关闭,该函数返回的就是键盘上按下的按键,
# 字母为ASCII码,特殊按键对应特殊的值:
'''
2.1 用matplotlib进行彩色和灰度image读写,打印彩色img的信息
'''
import matplotlib.pyplot as plt
# 用plt读入和显示图像
img3 = plt.imread('house.jpg') # 读入时就是一个矩阵,跟opencv一样,但是RGB频道
plt.figure('matplotlib_pyplotReadImg') # 打开一个名为''的窗口。
plt.imshow(img3)
plt.axis('off') # 关闭显示x,y轴上的数字。
plt.show()
print(img3.shape)
print(img3.size)
print(img3.dtype)
print(img3) #注意对比img3和img的频道顺序
'''
2.2用matplotlib显示灰度图
'''
import matplotlib.pyplot as plt
# 用plt读入和显示图像
img3 = plt.imread('house.jpg') # read a color image
imgray = img3[:,:,0] # gray image from 1st channel
fig = plt.figure()
plt.axis('off')
# Method 1
ax1 = fig.add_subplot(221) # add an sub image
ax1.imshow(imgray,cmap=plt.cm.gray) # display image
ax1.set_title('Gray image') # display title
plt.axis('off') # do not display axis
# Method 2:inverse gray
ax2 = fig.add_subplot(222)
ax2.imshow(imgray,cmap=plt.cm.gray_r)
ax2.set_title('Inverse gray image')
plt.axis('off')
# Method 3 <==>Method 1
ax1 = fig.add_subplot(223)
ax1.imshow(imgray,cmap='gray')
ax1.set_title('Gray image')
plt.axis('off')
# Method 4 <==>Method 2
ax2 = fig.add_subplot(224)
ax2.imshow(imgray,cmap='gray_r')
ax2.set_title('Inverse gray image')
plt.axis('off')
plt.savefig('house_ReadandShowImg_2_2.jpg') # save current image window.
'''
3.opencv的BGR与matplotlib的RGB频道切换
'''
import cv2
import matplotlib.pyplot as plt
# cv2读图,plt直接显示
img4 = cv2.imread('house.jpg')
img5 = cv2.cvtColor(img4,cv2.COLOR_BGR2RGB) # change channel from BGR 2 RGB
fig = plt.figure('image in BGR and RGB channel')
plt.axis('off')
ax1 = fig.add_subplot(121)
ax1.imshow(img4)
ax1.set_title('BGR channel')
plt.axis('off')
ax2 = fig.add_subplot(122)
ax2.imshow(img5)
ax2.set_title('RGB channel')
plt.axis('off')
plt.savefig('house_ReadandShowImg_3.jpg') # save current image window.
plt.show()
'''
4.使用pillow和matplotlib结合显示和保存图像
'''
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
# 用PIL读彩色图,并进行格式转换以用于不同目的
img6 = Image.open('house.jpg')
print(img6) # PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=280x200 ...
print(img6.format) # img类,JPEG格式。
print(img6.size)
print(img6.mode)
img6.show() # 调用系统软件显示图片。
img6 = np.array(img6) # pillow读的图不是矩阵,将图片转矩阵。
plt.figure('PIL_showImage')
plt.imshow(img6)
#print(img6)
plt.axis('off')
plt.savefig('houseCopy.jpg') # 注意存图必须在show之前,否则存储的图片一片空白。
plt.show()
# 用PIL读取灰度图
gray = Image.open('house.jpg').convert('L') # L为灰度图,RGB为真彩色,RGBA为加了透明频道。
gray.show() # 调用系统软件显示图片。
'''
5.比较全面的matplotlib最基本的图片显示技巧,可以对比cv2.imwrite和plt.savefig保存结果差异
'''
import matplotlib.pyplot as plt
im_lol1 = plt.imread('house.jpg')
im_lol2 = plt.imread('housecopy.jpg')
fig = plt.figure(figsize=(20,10)) # figsize参数:指定绘图对象的宽度和高度,单位为英寸;
# dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80。
# 因此本例中所创建的图表窗口的宽度为8*80 = 640像素
plt.axis("off")
ax = fig.add_subplot(121) # 图片以1行2列的形式显示
#plt.axis('off')
ax.imshow(im_lol1)
ax.set_title('Result of cv2.imwrite') # cv2.imwrite指令保存结果
ax = fig.add_subplot(122)
#plt.axis('off')
ax.imshow(im_lol2)
ax.set_title('Result of plt.savefig') # plt.savefig指令保存结果
plt.savefig('housetwo.jpg')
plt.show()
'''
6.scipy.misc:scipy.misc.imread
'''
from scipy import misc
import matplotlib.pyplot as plt
img7 = misc.imread('house.jpg')
print(img7.dtype)
print(img7.size)
print(img7.shape)
print(img7)
misc.imsave('house_misc.jpg',img7)
plt.imshow(img7)
plt.show()
'''
7.skimage:skimage.io.imread
'''
from skimage import io
img8 = io.imread('house.jpg')
print(img8.shape)
print(img8.dtype)
print(img8.size)
io.imshow(img8)
io.imsave('house_skimage.jpg',img8)
print(img8)