【问题标题】:work with binary (1 bit per pixel) images c++处理二进制(每像素 1 位)图像 C++
【发布时间】:2017-04-11 01:41:17
【问题描述】:

问题来了。有必要处理非常大的二进制图像(100000x100000 像素)。最初是使用 Qt 的 QImage 类完成的,它支持 Format_Mono 格式,将图像存储为每像素 1 位。总的来说,一切都很好,直到事实证明 QPainter 有有限的光栅化器,并且不能在尺寸更短(32767x32767)的图像上绘图,它只是被切断了。

我无法合并超过 32767x32767 的图像。然后,我开始仔细研究各个图书馆。据我了解,OpenCV 不支持这种格式。关于 ImageMagick,它支持将图像构建为每像素一位,并以相同的格式保存。然而,在处理图像时,仍然以每像素 8 位的形式存储,因此会出现 RAM 短缺。然后我决定尝试 CImg,但据我了解,它不支持 1bbp 格式:

一个实例图像已用内存的总大小(以字节为单位) 然后是'宽度x高度x深度x暗淡x sizeof(T)

其中sizeof(T)当然不能小于sizeof(char)...

QImage 原则上如何与它的 Format_Mono 格式一起工作很有趣,但老实说,我对源代码很纠结。

那么,我有下一个问题。是否有一个库实现了创建和处理二进制图像的能力,在这种情况下,它们真的以每像素 1 位的形式存储在 RAM 中?

【问题讨论】:

    标签: c++ image monochrome


    【解决方案1】:

    libvips 可以处理巨大的 1 位图像。它将它们解压缩到每个字节一个像素进行处理,但它只将当前正在处理的图像部分保留在内存中,所以你应该没问题。

    例如,这个小程序制作了一个 100,000 x 100,000 像素的黑色图像,然后从命令行将所有图像粘贴到随机位置:

    #!/usr/bin/env python
    
    import sys
    import random
    
    import gi
    gi.require_version('Vips', '8.0')
    from gi.repository import Vips
    
    # this makes a 8-bit, mono image of 100,000 x 100,000 pixels, each pixel zero
    im = Vips.Image.black(100000, 100000)
    
    for filename in sys.argv[2:]:
        tile = Vips.Image.new_from_file(filename, access = Vips.Access.SEQUENTIAL)
    
        im = im.insert(tile,
                       random.randint(0, im.width - tile.width),
                       random.randint(0, im.height - tile.height))
    
    im.write_to_file(sys.argv[1])
    

    我可以这样运行程序:

    $ vipsheader wtc.tif 
    wtc.tif: 9372x9372 uchar, 1 band, b-w, tiffload
    $ mkdir test
    $ for i in {1..1000}; do cp wtc.tif test/$i.tif; done
    $ time ./insert.py x.tif[bigtiff,squash,compression=ccittfax4] test/*.tif
    real    1m31.034s
    user    3m24.320s
    sys 0m7.440s
    peak mem: 6.7gb
    

    输出文件名上的[] 设置图像写入选项。在这里,我启用传真压缩并设置squash 选项。这意味着应该将 8 位单波段图像压缩到 1 位以进行写入。

    峰值内存结果来自top 中的 RES 观看。不幸的是,6.7gb 相当大,因为它必须为 1,000 个输入图像中的每一个保留输入缓冲区。

    如果您使用平铺的 1 位 tiff,您可以删除 access = 选项并使用需要随机访问的运算符,例如旋转。如果您尝试旋转条形 tiff,vips 将不得不将整个图像解压缩到一个临时磁盘文件,这可能是您不想要的。

    vips 具有合理范围的标准图像处理运算符,因此您可以做任何您想做的事情,只需将它们粘合在一起即可。如果需要,您可以在 C 或 C++ 中添加新的运算符。

    为了简洁起见,该示例使用 Python 编写,但如果您愿意,可以使用 Ruby、PHP、C、C++、Go、JavaScript 或命令行。它带有所有 Linux 和 BSD,它在 homebrew、MacPorts 和 fink 上,还有一个 Windows 二进制文件。

    【讨论】:

    • 谢谢。如果我将创建一些图像并尝试在其上绘制其他图像,它将以流式方式工作?
    • 是的,您可以将一张图片粘贴到另一张图片中。在 Python 中,im = im.insert(sub, 100, 100) 在坐标 (100, 100) 处将图像 sub 粘贴到图像 im 中。 vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/…
    • 很抱歉,您能否再回答一个我的问题。在您的示例中,您从文件加载了巨大的图像。但是如果需要使用 vips_black 或其他构造函数创建如此大的图像怎么办?如果我正确理解你,我不能那样做吗?
    • 是的,确切地说,使用black 并粘贴到其中。它应该可以正常工作。你想做什么样的处理?将一组 1 位 TIFF 组装成一个巨大的复合材料?
    • 是的,我需要创建 100000x100000 1 位 tiff 并粘贴到其中许多 7000x7000 1 位 tiff
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    相关资源
    最近更新 更多