编程小白最近跑程序,自己读数据集,大大小小的坑踩了无数。。
汇总一下吧~~
1. 使用save命令保存图片
img.save(img_path, optimize=True)
注:是针对Image格式的图片,数组形式的图片不能这么保存
可以使用 img = Image.fromarray(img) 将数组类型转换成Image格式
0-1之间的浮点数是不能保存成Image格式的
2. 使用opencv保存图片
import cv2
cv2.imwrite(img_path, img)
即使是0-1之间的浮点数,也可以用该方法进行保存,但会变成全黑的图片
img= img*255
将像素值乘255,就可以恢复彩色图片了。
用 skimage.util.random_noise(img, mode=‘gaussian’) 将图片进行加高斯噪声处理后,图片变成0-1浮点数了,就得用cv2保存图片了。
3. plt.savefig() 保存图片
使用 plt 保存图片时需要关闭坐标轴,以及去除掉图片周围的空白部分
plt.figure()
plt.imshow(img)
plt.axis('off') # 关闭坐标轴
plt.savefig(filename, bbox_inches='tight', pad_inches=0)
其中最重要的参数就是bbox_inches='tight'
和pad_inches=0
,如果想修改图片的分辨率可以使用plt.savefig中的dpi
参数,图片的大小就可以发生变化了。
该方法用来保存伪彩图真的巨好用!!!
4. 图片保存格式
图片保存成png还是jpg,也纠结了好久。 只知道png的精度要比jpg高,后来踩了一个大坑才知道jpg是会修改像素值的。(这个大坑就是——我要做语义分割任务,jpg把标签改了。。)
所以经过处理的图片还是保存成png格式吧。。
关于png是3通道还是4通道:
- 使用上述两种方法保存的png图片还是3通道的,读取之后可以直接送入神经网络
(“直接”是指:经过transpose(H,W,C) => (C,H,W) 和torch.tensor() ) - 如果是一个未知的png,(比如截屏保存),那么可能就是4通道的,输入网络之前需要压缩成3通道
from PIL import Image
# 通道转换
def change_image_channels(image, image_path):
# 4通道转3通道
if image.mode == 'RGBA':
r, g, b, a = image.split()
image = Image.merge("RGB", (r, g, b))
image.save(image_path)
# 1 通道转3通道
elif image.mode != 'RGB':
image = image.convert("RGB")
os.remove(image_path)
image.save(image_path)
return image
# 图片压缩
def image_compression(image):
w, h = image.size
print(w, h)
image.thumbnail((int(w / 1.1), int(h / 1.1)))
image.save("./car.png")
return image
if __name__ == "__main__":
image = Image.open("./timg.png")
new_image = process_image_channels(image, "./time.png")
print(new_image.mode)
5. 图片显示
我不太习惯用opencv显示图片,RGB会变成BRG,一般都是用plt
from matplotlib import pyplot as plt
plt.figure()
plt.imshow(img)
plt.show()
如果图片是uint8(0-255)会正常显示,
如果图片是浮点型0-255 会变成白图,img /= 255,变成0-1之间的浮点型就可以正常显示啦。
(输入到神经网络中,input和weight需要保持同类型,为了图片正常显示,需要除以255)
6. 保存16位的图片
深度图有时为了保存精度,需要保存成16位的图片(像素*1000 可以实现原图保存到小数点后三位)。
安装 numpngw 函数库
import numpngw
depth = (depth * 1000).astype(np.uint16)
numpngw.write_png('demo.png', depth)
亲测 Image.open()可以正常读取图片,用cv2.imread() 记得要打开图片原始的格式 —— img = cv2.imread(img_path, -1)
( ‘-1’ 表示图片的原始格式)