在 Python 中保存 1 位深的二进制图像

Jim*_*mbo 8 python binary png image computer-vision

我在 Python 中有一个二进制图像,我想将它保存在我的电脑中。一旦存储在我的计算机中,我需要它是一个 1 位深的 png 图像。我怎样才能做到这一点?我尝试了 PIL 和 cv2,但我无法以 1 位深度保存它。

che*_*yle 8

我发现自己处于需要创建大量二进制图像的情况,并且对在线可用信息感到沮丧。感谢这里和其他地方的答案和评论,我能够找到一个可接受的解决方案。@Jimbo 的评论是迄今为止最好的。下面是一些代码,用于重现我对在 python 中保存二进制图像的一些方法的探索:

加载库和数据:

from skimage import data, io, util #'0.16.2'
import matplotlib.pyplot as plt #'3.0.3'
import PIL #'6.2.1'
import cv2 #'4.1.1'
check = util.img_as_bool(data.checkerboard())
Run Code Online (Sandbox Code Playgroud)

棋盘图像的skimage尺寸为 200x200。如果没有压缩,作为 1 位图像,它应该由 (200*200/8) 5000 字节表示

要使用 保存skimage,请注意,如果数据不是uint,包会抱怨,因此进行转换。保存图像平均需要 2.8 毫秒,文件大小为 408 字节

io.imsave('bw_skimage.png',util.img_as_uint(check),plugin='pil',optimize=True,bits=1)
Run Code Online (Sandbox Code Playgroud)

使用matplotlib, 4.2ms 和 693 字节文件大小

plt.imsave('bw_mpl.png',check,cmap='gray')
Run Code Online (Sandbox Code Playgroud)

使用PIL0.5ms和 164 字节文件大小

img = PIL.Image.fromarray(check)
img.save('bw_pil.png',bits=1,optimize=True)
Run Code Online (Sandbox Code Playgroud)

使用cv2, 也会抱怨输入bool。尽管进行了 png 压缩,以下命令仍需要 0.4 毫秒并生成 2566 字节的文件大小...

_ = cv2.imwrite('bw_cv2.png', check.astype(int), [cv2.IMWRITE_PNG_BILEVEL, 1])
Run Code Online (Sandbox Code Playgroud)

PIL显然是速度和文件大小最好的。

当然我错过了一些优化,欢迎评论!


Ros*_*chi 4

使用:

cv2.imwrite(<image_name>, img, [cv2.IMWRITE_PNG_BILEVEL, 1])
Run Code Online (Sandbox Code Playgroud)

(这仍然会使用压缩,因此实际上每个像素很可能少于 1 位)

  • 我用 PIL.Image 中的“img.save(filename, bit=1)”解决了这个问题 (3认同)