[Pathology] OpenSlide를 활용한 병리 데이터 처리

es.Seong·2024년 3월 18일
0

개발환경
OS : MacOS
Python : 3.9.13
OpenSlide : 1.3.1

디지털 병리 이미지 데이터를 인공지능 연구에 활용하기 위해서는 Python에서 처리할 수 있는 형태로 변환이 필요하다. 예를 들어 Array와 같은 데이터셋을 만들기 편리한 형태로 만들어야 한다.
하지만 보통의 이미지와는 다르게 확장자가 의료분야에서 사용하는 확장자를 사용하기 때문에 일반적인 라이브러리로는 변환이 불가능하다.

Python에서는 OpenSlide라는 라이브러리를 통해 whole-slide image를 다룰 수 있다.

OpenSilde 설치

개발환경에서 pip 명령어를 통해 라이브러리를 설치해준다.

pip install openslide-python

코드 실행 시 오류 발생

라이브러리 실행 후 SVS파일을 열기 위해 코드를 실행했는데 다음과 같은 오류가 발생했다.

OSError: dlopen(libopenslide.0.dylib, 0x0006): tried: 'libopenslide.0.dylib' (no such file), ~

해결방법

맥에서는 Homebrew를 통해 OpenSlide를 설치해주면 해결된다고 한다.
터미널을 실행 후 다음 명령어를 입력하면 openslide가 설치된다. 단, Homebrew가 설치되어 있어야 사용이 가능하다.
아마 설치하며 PC 환경 설정을 자동으로 해준 것으로 보인다.

brew install openslide

다시 IDE에서 코드를 실행하면 정상적으로 코드가 실행될 것이다.

이미지 출력

이전 포스트에서 다운로드 받았던 sample.svs 파일을 읽어보자.

from openslide import OpenSlide

# SVS 파일 경로
svs_file_path = '../sample.svs'

# SVS 파일 열기
slide = OpenSlide(svs_file_path)

# 파일에서 기본 정보 추출
print("Slide dimensions:", slide.dimensions)
print("Slide level count:", slide.level_count)
print("Slide level dimensions:", slide.level_dimensions)
print("Slide level downsamples:", slide.level_downsamples)

# 특정 위치에서 이미지 조각 읽기 (예: 좌표 (x, y)에서 가로 512px, 세로 512px 크기)
x, y = 800, 500
width, height = 512, 512
image = slide.read_region((x,y),0, (width, height))

# 이미지 보기
image.show()

# 사용 후 슬라이드 파일 닫기 (자원 해제)
slide.close()



코드를 실행한 결과이다. print문에 출력한 변수는 이미지의 차원과 해상도 레벨의 개수 및 수치 등의 정보가 출력되고, 설정한 좌표에서 이미지 크기만큼 원본에서 Crop되어 출력된다.

데이터셋 만들기

딥러닝을 위해 불러온 여러장의 이미지들을 배열로 저장하여 4차원 Array로 만드는 코드 샘플이다.

import numpy as np
from openslide import OpenSlide

# SVS 파일 경로
svs_file_path = '../sample.svs'

# SVS 파일 열기
slide = OpenSlide(svs_file_path)
# SVS 파일을 읽어서 512x512 크기의 패치로 쪼개서 데이터셋을 생성하는 코드, 단 이미지 수는 사용자가 설정
img = [] 
for i in range(10):
    x, y = np.random.randint(0, slide.level_dimensions[0][0]-512), np.random.randint(0, slide.level_dimensions[0][1]-512)
    
    patch = slide.read_region((x,y), 0, (512, 512))
    patch = patch.convert("RGB")
    #patch.save(f"patch_{i}.png")
    # 이미지를 배열로 
    img.append(np.array(patch))
img = np.array(img)
img.shape

shape을 찍어보면 (10,512,512,3)과 같이 512x512크기의 3채널 이미지 열 장이 배열로 저장된 것을 확인할 수 있다.

이미지 시각화

배열로 저장한 열 장을 모두 시각화 해보자. 데이터셋을 만들 때 난수를 통해 좌표를 설정하였기 때문에 무작위로 이미지가 저장되었을 것이다.

#시각화
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 5, figsize=(20, 8))
for i in range(10):
    axes[i//5, i%5].imshow(img[i])
    axes[i//5, i%5].axis('off')
plt.show()

profile
Graduate student at Pusan National University, majoring in Artificial Intelligence

0개의 댓글