Припрема из претходних свезака¶
Све свеске се међусобно надограђују, тако да нам је неопходно да поновимо неке делове из претходних свески, што без додатног објашњења чинимо у овој секцији.
Овде нам је неопходно само учитавање библиотеки
Учитавање података за Србију са сателита Сентинел 2¶
Сада ћемо наш модел за класификацију намене земљишта применити на подацима из Србије. Као и за базу на којој је модел трениран, користићемо Сентинел 2 податке али регије која одговара Србији. У овом примеру смо изабрали Сентинел 2 снимке шире околине Шапца од 30. јуна 2021. године.
Учитавање једног Сентинел 2 производа у RGB домену¶
Сами подаци који представљају Сентинел 2 производе када се распакују садрже велики број снимака и метаподатака. У овој вежбанци ћемо се превасходно фокусирати на слике у видљивом спектру боја (практично стандардне слике какве свакодневно гледамо). Сам сателит има инструмент који снима у више спектралних опсега (енг. spectral bands), а нама су од интереса они који снимају на таласним дужинама црвене зелене и плаве боје који су довољни за формирање слике у боји. У питању су спектрални опсези са индексима b02, b03 i b04.
img_path_b02 = r"mldata\S2A_MSIL2A_20210630T093041_N0301_R136_T34TCQ_20210630T122807.SAFE\GRANULE\L2A_T34TCQ_A031450_20210630T093134\IMG_DATA\R10m\T34TCQ_20210630T093041_B02_10m.jp2"
img_path_b03 = r"mldata\S2A_MSIL2A_20210630T093041_N0301_R136_T34TCQ_20210630T122807.SAFE\GRANULE\L2A_T34TCQ_A031450_20210630T093134\IMG_DATA\R10m\T34TCQ_20210630T093041_B03_10m.jp2"
img_path_b04 = r"mldata\S2A_MSIL2A_20210630T093041_N0301_R136_T34TCQ_20210630T122807.SAFE\GRANULE\L2A_T34TCQ_A031450_20210630T093134\IMG_DATA\R10m\T34TCQ_20210630T093041_B04_10m.jp2"
Функција испод учитава сваки од снимака за појединачну боју и онда их комбинује у једну слику. Када је позовемо над путањама за сваку од слика имаћемо учитан целокупан снимак у боји. Слике су јако велике, па овај корак може потрајати који минут.
def load_sentinel_2_image_rgb(img_path_b02, img_path_b03, img_path_b04):
img_b02 = cv2.imread(img_path_b02, cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)
img_b03 = cv2.imread(img_path_b03, cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)
img_b04 = cv2.imread(img_path_b04, cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)
rgb = np.zeros((img_b02.shape[0], img_b02.shape[1], 3))
rgb[:, :, 0] = img_b04
rgb[:, :, 1] = img_b03
rgb[:, :, 2] = img_b02
rgb = rgb.astype(np.uint16)
return rgb
image = load_sentinel_2_image_rgb(img_path_b02, img_path_b03, img_path_b04)
Припрема исечка Сентинел 2 снимка за процесирање¶
Најпре је неопходно припремити учитану слику за обраду путем наше неуралне мреже. Јасно је да је слика веома велика, па ћемо процесирати њене исечке. Поред тога, иако се база на којој је модел трениран састоји од Сентинел 2 снимака, ипак осветљеност, сенке и угао снимања није скроз исти па постоје одређене перциптивне разлике између тих података и података за Србију. Када постоји разлика у подацима на којима је модел трениран и на којима се извршава кажемо да постоји доменска различитост (енг. domain discrapancy). Наравно пожељно је да домен на којем се тренира буде што сличнији домену на коме се модел тестира, што и овде јесте случај.
Доменска различитост је један од фундаменталних проблема са којим се сусрећемо када примењујемо машинско учење у пракси. Самим тим, постоји читава лепеза техника које се користе да се преброди доменска различитост и да се модел прилагоди новом домену - оне се здружено називају доменска адаптација (енг. domain adaptation).
Ми ћемо ради доменске адаптације применити најједноставнију варијанту где ћемо улазним сликама мало променити контраст и осветљеност тако да боље одговарају обсервацијама за Србију. То је поента функције испод. Сами параметри модификације су ручно изабрани посматрајући оба домена слика, мада је потпуно могуће и пожељно у пракси ово урадити на систематичан начин. Такође у зависности од примене, потребно је применити и сложеније технике доменске адаптације.
def prepare_rgb(image):
p_low, p_high = np.percentile(image, (1, 99))
image = exposure.rescale_intensity(image, in_range=(p_low, p_high))
image = image / image.max()
image = exposure.adjust_gamma(image, 0.9)
image += 0.05
image = np.clip(image, 0.0, 1.0)
return image
Сада ћемо изабрати исечак снимка Србије са којим ћемо радити. У питању је исечак величине 512x512 пиксела, а ми ћемо за почетак узети севернији део Шапца са делом реке Саве и обрадивим равничарским пределом са друге стране реке.
Можете се и сами играти и мењати прозор исечка који узимамо. Неки од предлога су дати у коментару испод, а можете и пробати неки свој.
# Шабац - севернији део и река Сава
CROP_START_COL = 9584
CROP_START_ROW = 4060
CROP_SIZE = 512
# Шабац - јужнији део
# CROP_START_COL = 9423
# CROP_START_ROW = 4329
# CROP_SIZE = 512
# Рума - јужни део
# CROP_START_COL = 10383
# CROP_START_ROW = 1626
# CROP_SIZE = 512
# Јарак - цело место и меандар Саве
# CROP_START_COL = 9929
# CROP_START_ROW = 2348
# CROP_SIZE = 512
# Вештачко језеро Ровни
# CROP_START_COL = 9721
# CROP_START_ROW = 9908
# CROP_SIZE = 512
sample_image_1 = image[CROP_START_ROW:CROP_START_ROW+CROP_SIZE, CROP_START_COL:CROP_START_COL+CROP_SIZE, :]
Прикажимо сада издвојени исечак.
plt.figure(figsize=(10, 10))
plt.imshow(prepare_rgb(sample_image_1))