합성, 마스킹, 모자이크

Landsat 8 TOA 반사율 컬렉션l8이라는 변수에 로드된 상태에서 다음 코드를 실행하면 최근 값 컴포지트가 생성됩니다.

코드 편집기 (JavaScript)

var l8 = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA');
var landsat2016 = l8.filterDate('2016-01-01', '2016-12-31');
Map.addLayer(landsat2016, visParams, 'l8 collection');

이 합성 이미지의 문제 중 하나는 구름이 가득하다는 것입니다. 컬렉션을 지도에 추가하면 Earth Engine에서 암시적으로 mosaic()를 호출합니다. 이때 컬렉션의 마지막 픽셀을 가져오는 대신 ImageCollection축소할 수 있습니다(이미지 컬렉션 축소에 대해 자세히 알아보기).

리듀서로 합성

이미지 영역에서 통계를 가져오는 리듀서가 처음 소개되었습니다. 이는 공간 감소입니다. 이미지 컬렉션을 이미지로 줄이는 것은 컬렉션이 시간 경과에 따른 이미지를 나타내는 경우 시간적 감소입니다. 사용하는 Reducer 유형에 따라 Earth Engine에서 중복 픽셀을 처리하는 방식이 정의됩니다. Landsat 8은 16일마다 지구의 동일한 지점을 방문합니다. 즉, 6개월 동안 약 12개의 이미지가 생성됩니다 (장면이 겹치는 경우 더 많음). 지도에 있는 각 픽셀은 컬렉션에 표시된 각 이미지의 픽셀 하나로 구성된 픽셀 스택에서 파생됩니다.

컬렉션을 지도에 추가하기만 하면 가장 최근 픽셀, 즉 스택의 최신 이미지에 있는 픽셀이 선택됩니다. 이 동작은 Earth Engine 리듀서를 사용하여 변경할 수 있습니다. 예를 들어 스택에서 가장 최근 픽셀을 가져오는 대신 스택에서 중간값을 선택하도록 Earth Engine에 지시할 수 있습니다. 이렇게 하면 값이 높은 구름과 값이 낮은 그림자가 제거됩니다. 중앙값 감소기를 사용하여 이미지 컬렉션을 줄이면 합성 값은 시간 경과에 따른 각 밴드의 중앙값입니다. 예를 들어 2016년에 Landsat 장면을 사용하는 경우:

코드 편집기 (JavaScript)

// Get the median over time, in each band, in each pixel.
var median = l8.filterDate('2016-01-01', '2016-12-31').median();

// Make a handy variable of visualization parameters.
var visParams = {bands: ['B4', 'B3', 'B2'], max: 0.3};

// Display the median composite.
Map.addLayer(median, visParams, 'median');

이 코드의 새로운 점은 이미지 컬렉션에 적용된 median() 메서드입니다. 필터링 메서드와 마찬가지로 이는 이미지 컬렉션에서 ee.Reducer()을 인수로 사용하는 더 일반적인 reduce() 메서드의 바로가기입니다. 코드 편집기의 문서 탭에서 ee.Reducer 패키지를 확인하여 모든 어스 엔진 리듀서 목록을 확인하세요. 이미지 컬렉션의 리듀서를 고려할 때 출력은 이미지이므로 숫자 이외의 출력이 있는 리듀서(예: histogram 또는 toList 리듀서)는 이미지 컬렉션과 함께 작동하지 않습니다.

Tutorial_api_06_median_composite
그림 6. Landsat 8 중간 합성.

중간값 컴포지션을 축소하면 그림 6과 같이 표시됩니다. 이 값은 이전에 만든 최근 값 컴포지트보다 훨씬 나아 보일 것입니다. 이 시점에서 잠시 물러나 중앙값 컴포지션을 만들기 위해 어떤 작업을 했는지 고려해 보는 것이 좋습니다. Earth Engine은 미국 대륙 전체에 걸쳐 Landsat 8 컬렉션을 로드하고 모든 픽셀의 중앙값을 계산했습니다. 데이터가 정말 많네요. 물론 이전에 했던 것처럼 먼저 컬렉션을 필터링하여 연간 중앙값을 계산할 수도 있습니다. 요점은 이러한 모든 이미지를 다운로드하고 이 합성 이미지를 만들어야 한다면 큰 프로젝트가 된다는 것입니다. Earth Engine을 사용하면 몇 초 만에 결과를 얻을 수 있습니다.

여기에서 컴포지팅 및 모자이크에 대해 자세히 알아보세요.

마스킹

중간값 컴포지션은 최근 값 컴포지션보다 개선되었지만 이미지의 일부를 마스크 처리하는 것이 좋습니다. 이미지에서 픽셀을 마스킹하면 해당 픽셀이 투명해지고 분석에서 제외됩니다. 이미지의 각 밴드에 있는 각 픽셀에는 마스크가 있습니다. 마스크 값이 0 이하인 항목은 투명해집니다. 마스크 값이 0보다 큰 값인 항목은 렌더링됩니다. 이미지의 마스크는 image1.mask(image2)와 같은 호출을 사용하여 설정됩니다. 이 호출은 image2 값을 가져와서 image1의 마스크로 만듭니다. 값이 0인 image2의 픽셀은 image1에서 투명하게 처리됩니다.

예를 들어 중간 합성의 모든 물 픽셀을 마스크로 처리하고 싶다고 가정해 보겠습니다. Earth Engine 데이터 카탈로그에 있는 Hansen 외(2013년)에서 설명하는 데이터 세트를 사용하여 물 마스크를 만들 수 있습니다. (Hansen et al. 데이터 세트에 대한 자세한 내용은 이 튜토리얼을 참고하세요.) 이 데이터 세트에서 물의 값은 2이고, 육지의 값은 1이며, '데이터 없음'의 값은 0입니다. 약간의 논리를 사용하여 육지가 없는 곳에 0이 있는 마스크 이미지를 만듭니다.

코드 편집기 (JavaScript)

// Load or import the Hansen et al. forest change dataset.
var hansenImage = ee.Image('UMD/hansen/global_forest_change_2015');

// Select the land/water mask.
var datamask = hansenImage.select('datamask');

// Create a binary mask.
var mask = datamask.eq(1);

// Update the composite mask with the water mask.
var maskedComposite = median.updateMask(mask);
Map.addLayer(maskedComposite, visParams, 'masked');

이 코드에는 자세히 설명할 만한 몇 가지 새로운 사항이 있습니다. 첫째, select() 함수는 이미지에서 관심 있는 밴드를 추출하는 데 유용합니다. 여기서는 관심 있는 대역인 datamask만 선택합니다. 다음 새로운 기능은 '같음'을 나타내는 논리 연산자 eq()입니다. eq(1)를 사용하여 datamask 밴드에 값 1이 없는 모든 픽셀 (물 또는 데이터가 없는 픽셀)이 결과 이미지에서 값 0을 갖는 바이너리 이미지를 만듭니다.

이 마스킹으로 인해 Hansen et al. 데이터 세트에 따라 육지에 있는 중앙값 컴포지트의 모든 픽셀이 표시되지만 물(또는 nodata) 위에 있는 픽셀은 투명하며 maskedComposite 이미지에 대해 실행하는 분석에서 제외됩니다.

모자이크

이미지 컬렉션, 논리 연산자, 마스크, 컴포지션의 개념을 결합하면 흥미로운 지도 제작 결과를 얻을 수 있습니다. 예를 들어 육지 픽셀은 트루 컬러로 표시되고 다른 모든 픽셀은 파란색으로 표시되는 이미지를 원하는 경우 다음과 같이 할 수 있습니다.

코드 편집기 (JavaScript)

// Make a water image out of the mask.
var water = mask.not();

// Mask water with itself to mask all the zeros (non-water).
water = water.mask(water);

// Make an image collection of visualization images.
var mosaic = ee.ImageCollection([
  median.visualize(visParams),
  water.visualize({palette: '000044'}),
]).mosaic();

// Display the mosaic.
Map.addLayer(mosaic, {}, 'custom mosaic');

이 코드에는 많은 내용이 포함되어 있으므로 하나씩 살펴보겠습니다. 먼저 not() 논리 연산자를 사용하여 앞에서 만든 마스크를 반전합니다. 구체적으로 not()는 모든 0을 1로, 모든 0이 아닌 값을 0으로 바꿉니다. 이 변수에는 nodata 픽셀도 포함되어 있으므로 water이라고 부르는 것은 완전히 정확하지는 않지만 현재의 지도 제작 맥락에서는 괜찮습니다. 다음은 '물'을 자체로 마스크하는 것입니다. 이로 인해 모든 물 픽셀이 1이고 나머지는 마스크 처리된 이미지가 생성됩니다. 마지막 단계는 이미지를 mosaic()와 결합하는 것입니다. mosaic()는 이미지 모음에서 작동하므로 이미지 모음 생성자에 결합하려는 이미지 목록을 전달한 다음 마지막 단계로 mosaic()를 호출합니다. 이 목록의 이미지 순서는 중요합니다. 구체적으로 출력 이미지에는 입력 컬렉션의 이미지 스택에서 마스크가 해제된 마지막 픽셀이 포함됩니다. 이 경우 물 레이어가 컬렉션의 마지막 (상단) 이미지이고 물이 발생하는 마스크되지 않은 픽셀만 포함하므로 작동합니다.

컬렉션의 이미지는 시각화 이미지입니다. 이미지에서 visualize()를 호출하면 전달하는 시각화 매개변수에 따라 3밴드 8비트 이미지로 변환됩니다. 기본 시각화 매개변수는 3밴드, 8비트 이미지에 적합하므로 이미지를 지도에 추가할 때 시각화 매개변수가 필요하지 않습니다. 결과는 그림 7과 같이 표시됩니다.

Tutorial_api_07_mosaic.png
그림 7. 물 영역을 균일한 색상으로 만드는 맞춤 모자이크

지금까지 이미지 컬렉션을 최신 값 컴포지트로 시각화하는 방법, 리듀서를 사용하여 이미지 컬렉션을 컴포지트하는 방법, 이미지 컬렉션을 마스킹하고 모자이크하여 맞춤 컴포지트를 만드는 방법을 살펴보았습니다. 다음 페이지에서는 컬렉션의 모든 이미지에 식생 지수를 추가하고 이 지수를 사용하여 '가장 푸른 픽셀' 컴포짓을 만드는 방법을 알아봅니다.