2017-02-02 1 views
0

문제는 다음과 같습니다. 매우 큰 바이너리 이미지 (100000x100000 픽셀)로 작업해야합니다. 처음에는 Qt의 QImage 클래스를 사용하여 이미지를 픽셀 당 1 비트로 저장하는 Format_Mono 형식을 지원합니다. QPainter는 래스터 라이저가 제한되어 있고 크기가 더 짧은 이미지 (32767x32767)를 그릴 수 없을 때까지는 문제가 없었습니다.바이너리 (픽셀 당 1 비트) 이미지 작업 C++

이미지를 32767x32767 이상 결합 할 수 없습니다. 그런 다음 개별 라이브러리를 자세히 살펴보기 시작했습니다. OpenCV는이 형식을 지원하지 않습니다. ImageMagick에 관해서는, 1 픽셀 당 1 비트의 이미지의 구축을 서포트 해, 같은 형식으로 보존합니다. 그러나 이미지 작업은 여전히 ​​픽셀 당 8 비트로 저장되므로 RAM이 부족합니다. 그럼 난 CIMG를 사용하기로 결정했습니다,하지만 난 이해가, 1bbp 형식을 지원 절하지 않습니다

(바이트) 하나 개의 인스턴스 이미지 다음이다위한 사용 된 메모리의 전체 크기 '폭 x 높이 x 깊이를 X 희미한 X는 sizeof (T) 원칙적으로 QImage가 Format_Mono 형식으로 작동하는 방법 그것은 재미 있었다

를 sizeof (T)는 물론 (문자)를 sizeof보다 작을 수 없습니다

...하지만, 솔직히, 나는 소스 코드에 얽혀 있었다.

그럼, 다음 질문이 있습니다. 바이너리 이미지를 만들고 작업 할 수있는 기능을 구현 한 라이브러리가 있습니까?이 경우 실제로 RAM의 픽셀 당 1 비트로 저장됩니까?

답변

2

libvips은 거대한 1 비트 이미지를 처리 ​​할 수 ​​있습니다. 처리를 위해 바이트 당 하나의 픽셀로 압축을 풀지 만 현재 처리중인 이미지의 일부만 메모리에 유지하므로 확인해야합니다. 나는이 같은 프로그램을 실행할 수 있습니다

#!/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]) 

:

예를 들어,이 작은 프로그램은 임의의 위치에서 명령 줄에서 모든 이미지에 붙여 넣습니다, 100,000 X 10 픽셀 검은 색 이미지를 만듭니다 :

$ 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 밴드 이미지를 쓰기 위해 1 비트로 압축해야합니다.

최대 mem 결과는 top의 RES를 보는 것입니다. 6.7gb는 1,000 개의 입력 이미지 각각에 대해 입력 버퍼를 유지해야하므로 불행히도 커집니다.

바둑판 식의 1 비트 티프를 사용하는 경우 access = 옵션을 제거하고 rotate와 같이 임의 액세스가 필요한 연산자를 사용할 수 있습니다. strip tiff를 돌리려고한다면, vips는 전체 이미지를 임시 디스크 파일로 압축해야 할 것입니다. 아마도 원하지 않을 것입니다.

vips에는 적당한 표준 이미지 처리 연산자가 있으므로 이미지를 결합하는 데 원하는 작업을 수행 할 수 있습니다. 원하는 경우 C 또는 C++로 새 연산자를 추가 할 수 있습니다.

이 예제는 간략하게하기 위해 파이썬으로 작성되었지만 원하는 경우 Ruby, PHP, C, C++, Go, JavaScript 또는 명령 줄을 사용할 수 있습니다. 그것은 모든 리눅스와 BSD, 자작, MacPorts 및 fink에 있으며 Windows 바이너리가 있습니다.

+0

감사합니다. 그리고 만약 내가 어떤 이미지를 만들고 그것에 다른 이미지를 그리면 스트리밍 스타일로 작동할까요? – bronstein87

+0

예. 한 이미지를 다른 이미지에 붙여 넣을 수 있습니다. 파이썬에서,'im = im.insert (sub, 100, 100)'은 좌표 (100, 100)에서 이미지'im'에 이미지'sub'를 붙여 넣습니다. http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/libvips-conversion.html#vips-insert – user894763

+0

죄송하지만 내 질문에 하나 더 대답 해 주실 수 있습니까? 귀하의 예제에서는 파일에서 거대한 이미지를로드했습니다. 그러나 vips_black 또는 다른 생성자를 사용하여 큰 이미지를 만들어야하는 경우에는 어떻게해야합니까? 내가 너를 제대로 이해한다면 나는 그것을 할 수 없다. – bronstein87

관련 문제