numpy를 사용하여 Python에서 TIFF (가져 오기, 내보내기) 작업


84

픽셀 데이터를 분석하고 수정 한 다음 다시 TIFF로 저장할 수 있도록 TIFF 이미지를 열고 numpy 배열로 가져 오는 파이썬 메서드가 필요합니다. (기본적으로 그레이 스케일의 광도 맵으로 픽셀 당 각 값을 나타냄)

TIFF와 관련된 PIL 메서드에 대한 문서를 찾을 수 없습니다. 알아 내려고했지만 "나쁜 모드"또는 "지원되지 않는 파일 형식"오류 만 발생했습니다.

여기서 무엇을 사용해야합니까?

답변:


103

첫째,에서 테스트 TIFF 이미지 다운로드 페이지 이라고를 a_image.tif. 그런 다음 다음과 같이 PIL로 열었습니다.

>>> from PIL import Image
>>> im = Image.open('a_image.tif')
>>> im.show()

이것은 무지개 이미지를 보여주었습니다. numpy 배열로 변환하려면 다음과 같이 간단합니다.

>>> import numpy
>>> imarray = numpy.array(im)

이미지의 크기와 배열의 모양이 일치하는 것을 볼 수 있습니다.

>>> imarray.shape
(44, 330)
>>> im.size
(330, 44)

그리고 배열에는 다음 uint8값이 포함 됩니다.

>>> imarray
array([[  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246],
       ..., 
       [  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246]], dtype=uint8)

배열 수정을 마치면 다음과 같이 PIL 이미지로 되돌릴 수 있습니다.

>>> Image.fromarray(imarray)
<Image.Image image mode=L size=330x44 at 0x2786518>

4
데이터 유형에 문제가 있습니다. 내 배열에 numpy.int16 숫자가있는 경우 일부에서는 잘 작동하지만 numpy.uint16의 경우 image.fromarray에서 "TypeError : Cannot handle this data type"
Jakob

4
fromarray의 소스를 살펴보면 서명되지 않은 16 비트 배열을 처리하는 것처럼 보이지 않습니다.
jterrace

@Jakob 2020 년 6 월 현재 PIL 은 색상 당 8 비트 이상의 색상 이미지를 지원하지 않으므로 다른 라이브러리를 사용하거나 직접 기능을 제공해야합니다.
Boris

56

TIFF 파일을 읽기 위해 matplotlib를 사용합니다.

import matplotlib.pyplot as plt
I = plt.imread(tiff_file)

I유형이 ndarray됩니다.

문서에 따르면 matplotlib는 기본적으로 PNG 만 읽으므로 TIFF를 처리 할 때 실제로 PIL이 작동하지만 이것은 잘 작동합니다.

plt.imsave저장 기능 도 있습니다 .


이것은 TIFF로 작업하는 가장 쉬운 방법입니다! 여러 가지 방법을 시도했고이 모든 것이 티켓이었습니다. 확실히 찬성하세요!
zachd1_618

보기 부분은 어떻습니까?
Monica Heddneck

5
matplotlib가 전략을 변경 한 것 같습니다.ValueError: Only know how to handle extensions: ['png']; with Pillow installed matplotlib can handle more images
strpeter

17

GDAL을 사용하여이 작업을 수행 할 수도 있습니다. 나는 그것이 지리 공간 툴킷이라는 것을 알고 있지만지도 제작 제품이 필요하지는 않습니다.

Windows 용 사전 컴파일 된 GDAL 바이너리에 대한 링크 (여기에서 Windows 가정) http://www.gisinternals.com/sdk/

어레이에 액세스하려면 :

from osgeo import gdal

dataset = gdal.Open("path/to/dataset.tiff", gdal.GA_ReadOnly)
for x in range(1, dataset.RasterCount + 1):
    band = dataset.GetRasterBand(x)
    array = band.ReadAsArray()

단일 TIF 또는 다중 페이지 TIF에 대한 위 코드는 무엇입니까? gdal을 사용하여 16 비트 tiff 스택을 nparray에로드하고 싶습니다.
user391339 2015 년

이것은 입력 데이터 유형을 읽거나 모든 것을 numpy의 float64로 이동해야합니다. .astype(sometype)통화 끝에 통화를 추가하여 전송할 수 있습니다 ReadAsArray(). 이것이 복사본인지 확실하지 않습니다 (테스트하지 않았 음).
Jzl5325

검토에서 @Chikinn : stackoverflow.com/review/suggested-edits/17962780는 xrange , 더 오타없는 xrange의 파이썬 2 버전입니다 range. 파이썬 3은 여전히 ​​적극적으로 개선되고 있지만 파이썬 2는 그렇지 않기 때문에이 편집을 수락했습니다.
abccd

12

pylibtiff 는 2020 년 6 월 현재 색상 당 8 비트 이상의 색상 이미지를 지원하지 않는 PIL보다 더 잘 작동했습니다 .

from libtiff import TIFF

tif = TIFF.open('filename.tif') # open tiff file in read mode
# read an image in the currect TIFF directory as a numpy array
image = tif.read_image()

# read all images in a TIFF file:
for image in tif.iter_images(): 
    pass

tif = TIFF.open('filename.tif', mode='w')
tif.write_image(image)

다음을 사용하여 pylibtiff를 설치할 수 있습니다.

pip3 install numpy libtiff

pylibtiff의 readme에도 언급 tifffile되어 있지만 시도하지 않았으며 표면적으로 오픈 소스이지만 코드를 더 이상 사용할 수 있다고 생각하지 않습니다 (PyPI 패키지에서 수동으로 추출하는 것 외에).


2
이것은 아주 좋습니다. 지금까지 tifffile은 SciKit의 skimage.external.tifffile에 포함되어 있지만,이 씨 크리스토프 Gohlke에서 tifffile.py 다운로드하는 경우 그것은 또한 모듈로 가져올 수 있습니다
lesolorzanov

7

내가 저자 인 pytiff 를 사용할 수도 있습니다 .

    import pytiff

    with pytiff.Tiff("filename.tif") as handle:
        part = handle[100:200, 200:400]

    # multipage tif
    with pytiff.Tiff("multipage.tif") as handle:
        for page in handle:
            part = page[100:200, 200:400]

상당히 작은 모듈이고 다른 모듈만큼 기능이 많지 않을 수 있지만 타일링 된 tiff 및 bigtiff를 지원하므로 큰 이미지의 일부를 읽을 수 있습니다.


이 기능은 정확히 내가 필요한 것입니다! (큰 파일의 작은 덩어리를 읽을 수 있음). 그러나 pip 설치를 시도하면 gcc 오류가 발생합니다
Fractaly

오류 메시지 로 문제 를 생성하면 문제 를 파악할 수 있는지 확인하겠습니다.
hnfl

예, 저도 관심이 있지만 설치하려고 할 때 오류가 발생했습니다. Windows 및 Ubuntu에서 pip를 사용하여 그렇게했습니다. 작동하지 않는 것은 유감입니다! 여기에 문제가 있습니다. github.com/FZJ-INM1-BDA/pytiff/issues/15
Dobedani

6

이미지 스택의 경우 scikit-image읽기, matplotlib표시 또는 저장 이 더 쉽습니다 . 다음 코드로 16 비트 TIFF 이미지 스택을 처리했습니다.

from skimage import io
import matplotlib.pyplot as plt

# read the image stack
img = io.imread('a_image.tif')
# show the image
plt.imshow(mol,cmap='gray')
plt.axis('off')
# save the image
plt.savefig('output.tif', transparent=True, dpi=300, bbox_inches="tight", pad_inches=0.0)

0

Vfx 세계에서 다양한 이미지 형식을 처리하기위한 표준 인 OpenImageIO에 대한 Python 바인딩을 사용하는 것이 좋습니다. 나는 PIL에 비해 다양한 압축 유형을 읽는 데 더 신뢰할 수 있음을 발견했습니다.

import OpenImageIO as oiio
input = oiio.ImageInput.open ("/path/to/image.tif")

이미 컴파일러가 없으면 Windows에 설치할 수없는 경계선입니다.
Jimmy Carter
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.