搞清楚skimage、matplotlib、cv2之间的共通与区别。
skimage
skimage下有很多包,常用的应该是io,data,transform
# read and show image
img1 = io.imread(fname) # dtype=uint8
print(img1.shape)
print(img1[:1,:3,:])
io.imshow(img1)
io.show()
Note:io想显示图片,需要加io.show(), just like plt.show(),应该都是基于PIL(pillow)的缘故。
- 左上角为 0,0,向下H,X,向右W,Y
- 读入dtype为uint8
- img1 = io.imread(fname, as_grey=True) 可以转为灰度图,dtype=float,0.0~1.0
- 正好说明io可以显示float(0.0~1.0)的矩阵,io的显示一句np.array的dtype
- 如果float时范围超出1.0,则会用颜色表示不同的数值。但保存是必须是[-1, 1]的范围,其中小于0的被置为0
- uint8不会超出范围,因为如果超出范围,会被uint8重新赋值,256为周期,即MOD256
io的读取、显示、存储均为RGB顺序。
# save image
io.imsave(sname, np.array)
transform
//TODO
matplotlib.pyplot
import os
import sys
import numpy as np
from skimage import io
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
fname = './0.jpg'
sname = './diy.jpg'
q
img = plt.imread(fname)
print(img.shape, img.dtype)
print(img.max(), img.min())
plt.imshow(img)
plt.show()
# Gray = R*0.299 + G*0.587 + B*0.114
diy = img[:, :, 0]*0.299 + img[:, :, 1]*0.587 + img[:, :, 2]*0.114
diy /= 255.
print(diy.shape, diy.dtype)
print(diy.max(), diy.min())
plt.imshow(diy)
plt.show()
io.imsave(sname, diy)
- plt不能显示和存储0-1 dtype=float的图像
- 顺序是RGB没错
- 是不是单通道都不能显示和存储?TODO uint8 dtype
- 是的。总结一下,只能显示和存储三通道uint8的图像
cv2
import cv2
cv2.imread(fname, flag)
# flag参数决定了cv是如何读入我们的图像的
# cv2.IMREAD_COLOR # 读入图片,任何与透明度相关通道都会被忽视,默认以这种方式读入
# cv2.IMREAD_GRAYSCALE # 以灰度图的形式读入图片
# cv2.IMREAD_UNCHANGED # 保留读取图片的原有颜色通道
- 以灰度图读入时并不会转换为float,仍然为uint8
- 顺序为BGR
- 均为 H W,这是没有问题的
- cv2可以显示0~1的float图像,小于0的都视为0,大于1的都视为1
- cv2不能存储float形式的图像,会出问题
- cv2存储uint8时遵循显示的规则
表格总结
func | io | plt | cv2 |
---|---|---|---|
read image | io.imread(fname) | plt.imread(fname) | cv2.imread(fname) |
shape & dtype | [H, W] dtype=uint8 | [H, W] dtype=uint8 | [H, W] dtype=uint8 |
grey | io.imread(fname, as_grey=True) | - | cv2.imread(cv2.IMREAD_GRAYSCALE) |
grey shape & dtype | float64, 0~1 | - | uint8, 0~255 |
channel order | RGB | RGB | BGR |
show image | io.imshow(img); io.show() | plt.imshow(img); plt.show() | cv2.imshow(winname, img) |
ps. | float64(超出0~1范围显示颜色) & uint8, 1 & 3 | 只能显示uint8,3 | float64(超出0~1范围置为0,1) & uint8, 1 & 3 |
save image | io.imsave(sname, img) | plt.imsave(sname, img) | cv2.imwrite(sname, img) |
ps. | float64(-1~1,<0=0) & uint8, 1 & 3 | uint8, 3 | uint8(可以显示float64,但不可以存储) |