반응형
변화 탐지(Change Detection)란?
변화 탐지(Change Detection)는 두 시점의 이미지를 비교하여 변화가 발생한 영역을 픽셀 단위로 분류하는 컴퓨터 비전 태스크입니다. 이번 시간에는 PyTorch를 이용하여 변화 탐지 데이터셋을 만드는 방법에 대해 알아보도록 하겠습니다.
변화 탐지 vs 의미론적 분할
- 변화 탐지
- 입력: 시점이 다른 두 이미지
- 출력: 픽셀별 변화 여부(0: 동일, 1: 변화)
- 활용 분야: 리모트 센싱, 감시, 재난 대응
- 의미론적 분할 (Semantic)
- 입력: 단일 이미지
- 출력: 픽셀별 클래스
- 활용 분야: 의료, 자율주행
대표 변화 탐지 데이터셋
LEVIR-CD
- 고해상도 항공 이미지 (1024×1024)
- 클래스: 변화 / 무변화 (2-class binary segmentation)
- 건물의 증/개축 변화에 특화
- 총 637 쌍 이미지 + 라벨
WHU-CD
- 도시 지역 항공사진 기반, 약 3,000 쌍
- 건물 변화 탐지에 활용
- 배경이 복잡하고 다양한 변화 패턴 포함
PyTorch용 LEVIR-CD Dataset 만들기
디렉토리 구조 예시
LEVIR-CD/
train/
A/ # T1 시점 이미지
B/ # T2 시점 이미지
label/ # 정답 마스크 (0/1)
PyTorch 코드 예제
from PIL import Image
import os
import torch
from torch.utils.data import Dataset
import torchvision.transforms as T
class LEVIRDataset(Dataset):
"""
Return: imgA (3,H,W), imgB (3,H,W), mask (1,H,W) float(0/1)
"""
def __init__(self, root_dir, split="train", transforms=None):
self.root_dir = root_dir
self.split = split
self.transforms = transforms
self.dirA = os.path.join(root_dir, split, "A")
self.dirB = os.path.join(root_dir, split, "B")
self.dirL = os.path.join(root_dir, split, "label")
if not (os.path.isdir(self.dirA) and os.path.isdir(self.dirB) and os.path.isdir(self.dirL)):
raise FileNotFoundError(
f"LEVIR 폴더 구조를 확인하세요.\n"
f"- {self.dirA}\n- {self.dirB}\n- {self.dirL}"
)
# A 기준 파일명 목록
self.names = sorted([os.path.basename(p) for p in glob(os.path.join(self.dirA, "*"))])
if len(self.names) == 0:
raise FileNotFoundError(f"'{self.dirA}' 안에 이미지가 없습니다.")
# B/label 존재 체크(빠진 파일 방어)
filtered = []
for n in self.names:
if os.path.exists(os.path.join(self.dirB, n)) and os.path.exists(os.path.join(self.dirL, n)):
filtered.append(n)
self.names = filtered
if len(self.names) == 0:
raise FileNotFoundError("A/B/label의 파일명이 일치하는 샘플이 없습니다. 파일명을 확인하세요.")
def __len__(self):
return len(self.names)
def __getitem__(self, idx):
name = self.names[idx]
pA = os.path.join(self.dirA, name)
pB = os.path.join(self.dirB, name)
pL = os.path.join(self.dirL, name)
imgA = Image.open(pA).convert("RGB")
imgB = Image.open(pB).convert("RGB")
mask = Image.open(pL).convert("L") # 0/255
if self.transforms:
imgA, imgB, mask = self.transforms(imgA, imgB, mask)
else:
# 최소 기본값
imgA, imgB, mask = CDToTensor()(imgA, imgB, mask)
return imgA, imgB, mask
변화 탐지는 A/B/Mask가 픽셀 단위로 정렬돼야 하므로, Resize/Flip/Crop 같은 변환은 반드시 동일하게 적용하고, 색감 변화(ColorJitter)처럼 라벨에 적용할 수 없는 변환은 이미지에만 적용합니다.
변화 탐지 모델 구조
변화 탐지 모델은 대부분 다음과 같은 구조를 따릅니다.
- 두 이미지를 각각 backbone (e.g., ResNet)으로 인코딩
- Feature 차이 계산 또는 융합
- 디코더로 변화 마스크 출력
대표 모델
- Siamese U-Net
- STANet
- BIT (Bi-Temporal Transformer)
- ChangeFormer (SOTA)
마무리
PyTorch를 이용하여 변화 탐지 데이터셋을 어떻게 만드는지 살펴보았습니다. 다음 시간에는 모델 구성 및 학습 방법을 PyTorch로 작성하는 방법을 알아보도록 하겠습니다.
관련 내용

반응형
'실전 예제, 프로젝트' 카테고리의 다른 글
| [실전 예제/객체 추적/PyTorch] MOT 데이터셋으로 객체 추적 데이터셋 구성하기 (0) | 2025.04.27 |
|---|---|
| [실전 예제/리스트/파이썬] 리스트 요소에 같은 연산을 적용하는 6가지 방법 (0) | 2025.04.22 |
| [실전 예제/인스턴스 분할/PyTorch] 인스턴스 분할 튜토리얼: COCO 데이터셋으로 PyTorch 데이터셋 만들기 (0) | 2025.04.19 |
| [실전 예제/객체 탐지/PyTorch] 객체 검출 튜토리얼: COCO 데이터셋으로 PyTorch 데이터셋 만들기 (0) | 2025.04.19 |
| [실전 예제/이미지 분류/PyTorch] 이미지 분류 튜토리얼: CIFAR-10과 ImageNet으로 PyTorch 데이터셋 만들기 (0) | 2025.04.19 |