의료영상 전처리
의료영상 전처리
의료영상 잡음 유형
- 양자화 잡음 (Quantization Noise) : 디지털 변환 과정에서 발생하는 신호 손실, 픽셀 값이 근사값으로 변환되면서 발생하는 불연속적인 변화
- 그레인 잡음 (Grain Noise) : 필름 기반 영상에서 발생하는 미세한 잡음, 디지털 변환 과정에서도 일부 발생 가능
- 가우시안 잡음 (Gaussian Noise) : 센서 감도, 전자적 신호 증폭 과정에서 발생, 픽셀 값이 정규 분포를 따르는 랜덤 노이즈를 포함
- 푸아송 잡음 (Poisson Noise) : 저조도 영상에서 발생하는 확률적 잡음, 촬영 시 빛이 감지되는 과정에서 변동이 생기며 발생
- 스펙클 잡음 (Speckle Noise) : 초음파 및 SAR(합성 개구 레이더) 영상에서 흔히 발생, 영상 표면에 얼룩처럼 나타나는 잡음
- 구조물 잡음 (Structural Noise) : 조직 구조, 기기 특성에 따라 반복적인 패턴이 잡음처럼 나타남, 특정 필터를 적용하여 제거 가능
clariCT.AI를 이용한 잡음 제거
이미지 처리 기법
- CLAHE 처리:
- 입력 이미지를 작은 블록으로 분할
- 타일별 히스토그램 계산
- 픽셀 강도 분포 평탄화
- 영상 크롭 (Image Cropping):
- ROI(Region of Interest, 관심 영역)만을 남기고 불필요한 영역 제거
- 연산 속도를 향상시키고 저장 공간 절약 가능
- CT Number 정규화:
- CT 영상에서 픽셀 값(HU, Hounsfield Unit)을 일정 범위로 변환
- 다양한 영상 간의 일관된 해석 가능
이미지 전처리 기법
차이점 추출
sub_image = image - image_noVessel sub_image = sub.image + 128 data = nib.load(ct_folder) image = data.get_fdata() slice_index422 Original_ct = cv2.normalize(ct, None, 0, 255, cv2.NORM-MINMAX) Original_ct = Original_ct as type (np.unit8) plx.axis("off") plt.imshow(Original_ct, cmap='gray') 이미지 회전
plt.imshow = cv2.rotate(Original_ct, cv2, ROTATE_90_CLOCKWIST) 이미지 추출
rescale_slope = 1 rescale_intercopt = 0 extract_ct = np.clit(ct_numbers, 54, 66) image_bytes = enc-image.tobytes bytes/pixecl : round(len(image_bytes)/(np.shape(dst)[0] + np.shape(dst)[1]))2} width : {np.shape(dst[0])} height : {np.shape(dst[1])} 임계값(th)와 임계값을 넘는 경우 반환할 값 (max-value) 입력
dst = image.capy h = image.shape[0] w = image.shape[1] th=120 (예시) max_value=255 for i in range(o,h): for j in range(0,w): if image[i,j] > th dst[i,j] = max-value else: dst[i,j]=0 LUT(Look Up Table)과 멱함수(Power Transform) : 사진마다 함수적용할 때 지정해줌
예시 : sigmoid function (대조도 높임)
def sigmoid.transform(a,c,LUT): i=0 for i in range(i,256): tmp=255.0/(1.0+np.exp(-a*((i/255.0-c)))) if tmp>255: tmp=255 #(255로 제한) LUT[i]=tmp def view_1d(mat, size, data, DX, DY, yscale): cv2.rectangle(mat,(0,0),(256,256),(0,0,0),-1) i=0 for i in range(0,size-1): cv2.line(mat, (DX+i, DY-yscale*data[i]),(DX+i.DY-ysacle*data[i+1]),(0,125,0),2) LUT=np.zeros(256,np.unit8) sigmoid_transform(a,c,LUT) view=np.zeros((256,256,156,3),np.unit8) w=image.shape[1] h=image.shape[0] for in range(o,h): for j in range(o,w): dst[i][j]=LUT[image[i][j]] def view_ld(mat, size, data, DX,DY,yscale): cv2.rectangle(mat,(0,0),(256,256),(0,0,0),-1) i=0 for i in range(0,size-1): cv2.line(mat,(DX+i,DY-yscale*data[i], (DX+1, DY-yscale*data[i+[]],(0,125,0),2))) view_ld(view,25,LUT,0,256,1) plt.figure(fig size=(30,10)) plt.sublot(131) plt.imshow(image,cmap='gray') plt.subplot(132) plt.subplot(133) view_ld(view,256,LUT,0,256,1) plt.imshow(view) 노이즈와 필터
컨블루션(convolution)연산 : 테투리 잡기. input의 채널수와 filter의 채널 수는 같아야 한다.
img=cv.impread("IM.~~~") kernel_1 = np.array([[0,1,0],[-1,4,-1],[0,-1,0]]) kernel_2 = np.array([[-1,-1,-1],[-1,8,-1],[-1,-1,-1]]) dst = cv2.filter2D(img,-1,kernel_1) print(np.max(dst),np.min(dst)) dst=np.clip(dst,0,252) 푸리에 변환
: 주파수 성분 분석, 어디가 주파수 성분dl 많이 포함 하는지 알 수 있다.
import numpy as np import cv2 # 푸리에 변환 적용 dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT) dft_shift = np.fft.fftshift(dft) # 주파수 스펙트럼 시각화 magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1])) plt.imshow(magnitude_spectrum, cmap='gray') 대역필터
- Low Pass Filter : 고주파 성분 제거
- High Pass Filter : 저주파 성분 제거
- 밴드 패스 필터 : 특정 주파수 대역만 통과시키고 나머지 제거
- 밴드 스탑 필터 : 특정 주파수 대역을 제거하고 나머지 주파수 통과
- Gaussian Sharpening : 고주파 정보를 강조하고 저주파 정보를 억제
Multi-frequancy
영상선명화 : 여러 주파수 대역을 동시에 다루는 영상처리 기법
저주파와 고주파 수 성분을 모두 고려 -> 선명도를 높임
다중 해상도 이미지 생성
스케일별 특징 추출
Gaussain/Laplacian Pyramid
gaussian_pyr = [image.copy()] for _ in range(4): gaussian_pyr.append(cv2.pyrDown(gaussian_pyr[-1])) # 해상도 축소 laplacian_pyr = [gaussian_pyr[-1]] for i in range(4, 0, -1): laplacian = cv2.subtract(gaussian_pyr[i - 1], cv2.pyrUp(gaussian_pyr[i])) laplacian_pyr.append(laplacian) This post is licensed under CC BY 4.0 by the author.