tensorflow 2
处理图片十分简便,其内部的tensorflow.image
工具包更是十分强大。
当然opencv
也很强大,但opencv
对于png
和jpg
解析出来的格式是不一致的,一种是归一化的值,一种是非归一化的值,后续处理仍然很麻烦.
因而用tensorflow.image.decode_png()
、tensorflow.image.decode_jpeg()
、tensorflow.image.encode_png()
、tensorflow.image.encode_jpeg()
来操作图片就是一个明智选择。
但是不免有的图片挂羊头卖狗肉,明明后缀是jpg
,但是用decode_jpeg
就是不能读或写,就是给你报错。用图片查看器打开也正常,又不见什么问题,我们怎么处理呢?
结论
最好的办法是单独把图片拿出来另存一遍替换掉。
问题1复现
在lfpw
数据集中,有几张图片是有坑的。
诸如读图报错的lfpw_testImage_102.jpg
、写图报错的lfpw_testImage_339.jpg
等等,最好的办法是单独把图片拿出来另存一遍替换掉,否则使用如下代码读图会出现错误。
import tensorflow as tf
path1 = '/xxxxxx/lfpw_trainImage_339.jpg' #原图片
img = tf.io.read_file(path1)
img_tf = tf.image.decode_jpeg(img)
print(img_tf)
报错:
InvalidArgumentError: Expected image (JPEG, PNG, or GIF), got unknown format starting with xxxxxxxxx
一般来讲,这是传入文件path
并非jpg格式造成的,删除对应的文件即可,但是!!!
我是加了格式检测的!!!
suffix = new_path.split('.')[-1].lower()
if suffix not in ['jpeg','jpg']:
print(f"仅支持jpg、jpeg后缀的图片,而你竟想生成后缀为{suffix}的图片")
exit()
我这张图片确实是jpg格式的,而且用图片查看器也没有问题。
原因还是在与图片本身,往往图片查看器会根据图片格式来打开图片,但是如果你将jpg文件重命名成其他格式,图也是可以打开的,因为一个图片查看器有试错机制,能够打开挂羊头卖狗肉的图片。
问题2复现
而lfpw_testImage_102.jpg
则是另外一个问题,
你把它resize以后再次存储,会有这个问题:
import tensorflow as tf
path1 = '/xxxxxx/lfpw_trainImage_102.jpg' #原图片
new_path = 'xxxxxxx.jpg' #图片保存路径
# 读
img = tf.io.read_file(path1)
img_tf = tf.image.decode_jpeg(img)
#resize
tf.image.resize(img_tf, [12, 12], antialias=True)
#写入
new_img = tf.image.encode_jpeg(img_tf)
with tf.io.gfile.GFile(new_path, 'wb') as file:
file.write(new_img.numpy())
写入时候回报错:image must have 1 or 3 channels, got [12,12,4] [Op:EncodeJpeg]
,
这是通道数的问题了。
综上所述
用图片查看器打开图片,重新保存图片,保存时候,格式选择原来的格式即可,注意不要更改长宽。