BAB 3: Pertanian Presisi & Analisis Citra Drone (UAV)
#Bagian A: QGIS
#3.1. Mengekstrak Canopy Height Model (CHM)
Digital Surface Model (DSM) merekam pucuk pohon sekaligus permukaan tanah. Digital Terrain Model (DTM) hanya merekam tanah murni. Untuk mengetahui tinggi pohon murni (Canopy Height Model), Anda harus mengurangkan keduanya.
#Langkah Eksekusi (Cara Visual):
- Buka Processing Toolbox > Raster Analysis > Raster Calculator.
- Masukkan ekspresi: "DSM_Drone@1" - "DTM_Drone@1".
- Simpan sebagai CHM_Kebun.tif.
- Atur simbologi CHM_Kebun ke Singleband pseudocolor dengan gradasi warna Hijau ke Merah. Pohon-pohon tinggi akan tampak merah menyala, sedangkan tanah kosong bernilai 0 (hijau).

#3.2. Menghitung Jumlah Tegakan Pohon (Local Maxima)
Anda mencari titik tertinggi pada setiap gundukan kanopi di citra CHM. Setiap titik tertinggi dianggap satu pucuk pohon.
#Langkah Eksekusi:
- Buka Processing Toolbox > Raster Analysis > Find Local Peaks (Algoritma native QGIS 4.x).
- Input Raster: CHM_Kebun.tif.
- Distance/Radius: Atur ke 4 (Meter). Ini sangat krusial. Jika jarak rata-rata antar pohon (misalnya sawit) adalah 8 meter, masukkan setengahnya agar algoritma tidak menghitung cabang pohon sebagai pohon baru.
- Output: Layer titik vektor Pucuk_Pohon.shp. Tabel atributnya otomatis berisi nilai tinggi dari citra CHM.

#3.3. Eksekusi Tingkat Lanjut: Pemrosesan Latar Belakang (QgsTask) untuk Ratusan Citra Drone
Citra drone sangat berat. Memproses 50 ubin (tiles) ortofoto secara berurutan akan membuat antarmuka QGIS hang dan Not Responding. Anda dapat mengatasinya dengan membuat tugas paralel di latar belakang memakai QgsTask pada Python 3.

# [SKRIP 3.1: Batch Processing Citra Drone di Latar Belakang (Non-Blocking)]
# Penulis: Badar Mubarok Yogaswara
import os
import processing
from qgis.core import QgsTask, QgsApplication, QgsMessageLog, Qgis
folder_input = "D:/Data_Drone/Ortofoto_Mentah/"
folder_output = "D:/Data_Drone/NDVI_Hasil/"
def proses_batch_ndvi(task, folder_in, folder_out):
QgsMessageLog.logMessage("Memulai Batch Processing di Latar Belakang...", "Analisis Drone", Qgis.Info)
file_list = [f for f in os.listdir(folder_in) if f.endswith('.tif')]
total_files = len(file_list)
for i, file_name in enumerate(file_list):
if task.isCanceled():
return False
path_in = os.path.join(folder_in, file_name)
path_out = os.path.join(folder_out, f"NDVI_{file_name}")
processing.run("qgis:rastercalculator", {
'EXPRESSION': '("{}@1" - "{}@2") / ("{}@1" + "{}@2")'.format(path_in, path_in, path_in, path_in),
'LAYERS': [path_in],
'OUTPUT': path_out
})
task.setProgress((i + 1) / total_files * 100)
return True
def task_selesai(exception, result=None):
if result:
QgsMessageLog.logMessage("✅ Batch Processing Selesai 100%!", "Analisis Drone", Qgis.Success)
else:
QgsMessageLog.logMessage("❌ Proses dibatalkan atau error.", "Analisis Drone", Qgis.Warning)
task_ndvi = QgsTask.fromFunction("Kalkulasi NDVI 50 Ubin", proses_batch_ndvi,
on_finished=task_selesai,
folder_in=folder_input, folder_out=folder_output)
QgsApplication.taskManager().addTask(task_ndvi)Skrip alternatif (memakai native:rastercalc):
# [SKRIP 3.1 - ALTERNATIF: Batch Processing Citra Drone di Latar Belakang (Non-Blocking)]
# Penulis: Badar Mubarok Yogaswara
# Perbedaan dengan Skrip 3.1: memakai native:rastercalc (terdokumentasi) dengan layer bernama,
# bukan qgis:rastercalculator dengan nama layer berupa jalur berkas.
import os
import processing
from qgis.core import QgsTask, QgsApplication, QgsMessageLog, Qgis, QgsRasterLayer
folder_input = "D:/Data_Drone/Ortofoto_Mentah/"
folder_output = "D:/Data_Drone/NDVI_Hasil/"
def proses_batch_ndvi(task, folder_in, folder_out):
QgsMessageLog.logMessage("Memulai Batch Processing di Latar Belakang...", "Analisis Drone", Qgis.Info)
file_list = [f for f in os.listdir(folder_in) if f.endswith('.tif')]
total_files = len(file_list)
for i, file_name in enumerate(file_list):
if task.isCanceled():
return False
path_in = os.path.join(folder_in, file_name)
path_out = os.path.join(folder_out, f"NDVI_{file_name}")
# Beri nama layer agar bisa dirujuk di ekspresi
layer_in = QgsRasterLayer(path_in, "ortofoto", "gdal")
processing.run("native:rastercalc", {
'EXPRESSION': '("ortofoto@1" - "ortofoto@2") / ("ortofoto@1" + "ortofoto@2")',
'LAYERS': [layer_in],
'OUTPUT': path_out
})
task.setProgress((i + 1) / total_files * 100)
return True
def task_selesai(exception, result=None):
if result:
QgsMessageLog.logMessage("✅ Batch Processing Selesai 100%!", "Analisis Drone", Qgis.Success)
else:
QgsMessageLog.logMessage("❌ Proses dibatalkan atau error.", "Analisis Drone", Qgis.Warning)
task_ndvi = QgsTask.fromFunction("Kalkulasi NDVI 50 Ubin", proses_batch_ndvi,
on_finished=task_selesai,
folder_in=folder_input, folder_out=folder_output)
QgsApplication.taskManager().addTask(task_ndvi)#Bagian B: ArcGIS Pro
#3.1. Mengekstrak Canopy Height Model (ArcGIS Pro)
Konsepnya sama dengan Bagian A: tinggi pohon diperoleh dengan mengurangkan DTM dari DSM.
#Langkah Eksekusi (Cara Visual):
- Buka alat Raster Calculator (kelompok Spatial Analyst Tools). [CEK]
- Masukkan ekspresi: "DSM_Drone" - "DTM_Drone".
- Simpan hasilnya sebagai CHM_Kebun.tif.
- Atur simbologi CHM_Kebun dengan gradasi warna hijau ke merah, agar pohon tinggi tampak merah dan tanah kosong hijau. [CEK]
#3.2. Menghitung Jumlah Tegakan Pohon (ArcGIS Pro)
Tujuannya sama: setiap titik tertinggi pada gundukan kanopi dianggap satu pucuk pohon. Di ArcGIS Pro hal ini disusun dari tiga alat.

#Langkah Eksekusi:
- Jalankan Focal Statistics pada CHM_Kebun.tif. Pilih statistik MAXIMUM dan lingkungan berbentuk lingkaran (Circle) dengan radius 4 dalam satuan peta (meter). Simpan hasilnya, misalnya sebagai Fokal_Maks.tif.
- Pilih sel yang nilainya sama dengan maksimum di sekitarnya, misalnya lewat Raster Calculator: Con("CHM_Kebun.tif" == "Fokal_Maks.tif", "CHM_Kebun.tif"). Sel lain menjadi NoData. [CEK]
- Ubah hasilnya menjadi titik dengan Raster to Point. Simpan sebagai Pucuk_Pohon. Tinggi pohon tersimpan di kolom Grid_code.
#3.3. Eksekusi Tingkat Lanjut: Pemrosesan Batch dengan ArcPy
ArcGIS Pro tidak punya padanan langsung QgsTask. Pemrosesan banyak ubin dilakukan sebagai skrip batch. Esri menyediakan opsi paralel berupa Parallel Processing Factor dan modul Python multiprocessing; keduanya perlu Anda coba sendiri. [CEK]

Buka jendela Python di ArcGIS Pro dan jalankan skrip berikut:
# [SKRIP 3.1-Pro: Batch Processing Citra Drone dengan ArcPy]
# Penulis: Badar Mubarok Yogaswara
# [CEK] Cocokkan dengan versi Anda. Butuh ekstensi Spatial Analyst atau Image Analyst.
import os
import arcpy
from arcpy.sa import Raster, Float
arcpy.CheckOutExtension("Spatial")
arcpy.env.overwriteOutput = True
folder_input = r"D:\Data_Drone\Ortofoto_Mentah"
folder_output = r"D:\Data_Drone\NDVI_Hasil"
arcpy.env.workspace = folder_input
daftar = arcpy.ListRasters("*", "TIF")
total = len(daftar)
print(f"Memulai batch {total} ubin...")
for i, nama in enumerate(daftar, start=1):
# Urutan band mengikuti Skrip 3.1 QGIS: pastikan Band_1 = NIR dan Band_2 = Red
band1 = Float(Raster(os.path.join(folder_input, nama, "Band_1")))
band2 = Float(Raster(os.path.join(folder_input, nama, "Band_2")))
ndvi = (band1 - band2) / (band1 + band2)
ndvi.save(os.path.join(folder_output, "NDVI_" + nama))
print(f"{i}/{total} selesai: {nama}")
arcpy.CheckInExtension("Spatial")
print("Batch selesai.")#Bagian C: ArcMap 10.8
#3.1. Mengekstrak Canopy Height Model (ArcMap)
#Langkah Eksekusi (Cara Visual):
- Buka alat Raster Calculator (kelompok Spatial Analyst Tools). [CEK]
- Masukkan ekspresi Map Algebra: "DSM_Drone" - "DTM_Drone".
- Simpan hasilnya sebagai CHM_Kebun.tif.
- Atur simbologi dengan gradasi hijau ke merah. [CEK]
#3.2. Menghitung Jumlah Tegakan Pohon (ArcMap)

- Jalankan Focal Statistics pada CHM_Kebun.tif dengan statistik MAXIMUM dan lingkungan lingkaran (Circle) berradius 4 dalam satuan peta (meter). Focal Statistics mendukung MAXIMUM untuk raster desimal.
- Pilih sel yang sama dengan maksimum di sekitarnya dengan Con (dari Raster Calculator): Con("CHM_Kebun.tif" == "Fokal_Maks.tif", "CHM_Kebun.tif"). [CEK]
- Ubah hasilnya menjadi titik dengan Raster to Point; tinggi pohon ada di kolom Grid_code.
#3.3. Eksekusi Tingkat Lanjut: Pemrosesan Batch dengan ArcPy (Python 2.7)
Tidak ada padanan langsung QgsTask. Jalankan skrip dari luar ArcMap (misalnya lewat IDLE atau command line) agar antarmuka ArcMap tidak hang. [CEK] Parallel Processing Factor ada di ArcMap, tetapi tidak didukung di Background Geoprocessing 64-bit dan hanya dipakai sebagian alat.

Jalankan skrip berikut dari luar ArcMap:
# [SKRIP 3.1-ArcMap: Batch Processing Citra Drone dengan ArcPy]
# Penulis: Badar Mubarok Yogaswara
# [CEK] Cocokkan dengan versi Anda. Butuh ekstensi Spatial Analyst.
from __future__ import print_function # agar print() berlaku di Python 2.7
import os
import arcpy
from arcpy.sa import Raster, Float
arcpy.CheckOutExtension("Spatial")
arcpy.env.overwriteOutput = True
folder_input = r"D:\Data_Drone\Ortofoto_Mentah"
folder_output = r"D:\Data_Drone\NDVI_Hasil"
arcpy.env.workspace = folder_input
daftar = arcpy.ListRasters("*", "TIF")
total = len(daftar)
print("Memulai batch {} ubin...".format(total))
for i, nama in enumerate(daftar, 1):
# Urutan band mengikuti Skrip 3.1 QGIS: pastikan Band_1 = NIR dan Band_2 = Red
band1 = Float(Raster(os.path.join(folder_input, nama, "Band_1")))
band2 = Float(Raster(os.path.join(folder_input, nama, "Band_2")))
ndvi = (band1 - band2) / (band1 + band2)
ndvi.save(os.path.join(folder_output, "NDVI_" + nama))
print("{}/{} selesai: {}".format(i, total, nama))
arcpy.CheckInExtension("Spatial")
print("Batch selesai.")#Ringkasan, Latihan, dan Bantuan Bab 3
#Ringkasan
- Canopy Height Model (CHM) adalah DSM dikurangi DTM.
- Pohon dihitung dari titik tertinggi pada tiap gundukan kanopi, dengan radius pencarian sebagai pengaturan kuncinya.
- QgsTask menjalankan pemrosesan banyak ubin di latar belakang agar QGIS tetap bisa dipakai.
- [ArcGIS Pro / ArcMap] CHM dengan Raster Calculator; pucuk pohon dengan Focal Statistics (MAXIMUM), Con, dan Raster to Point; batch lewat skrip ArcPy.
#Latihan
- Hitung CHM untuk satu petak contoh, lalu bandingkan tinggi satu pohon yang Anda kenal dengan nilai pada CHM.
- Hitung jumlah pohon pada petak 1 hektar dengan radius 3, 4, dan 5 meter. Bandingkan dengan hitungan manual pada citra: radius mana yang paling mendekati?
- Jalankan skrip 3.1 pada 3 ubin contoh sebelum memakainya untuk seluruh 50 ubin. [CEK]
- [ArcGIS Pro / ArcMap] Ulangi hitungan pohon dengan Focal Statistics pada radius yang sama dan bandingkan jumlahnya dengan hasil QGIS.
#Jika terjadi masalah
- Jumlah pohon terlalu banyak: radius terlalu kecil sehingga cabang ikut terhitung sebagai pohon. Perbesar radius.
- Jumlah pohon terlalu sedikit: radius terlalu besar sehingga pohon yang berdekatan tergabung.
- QGIS tidak merespons saat memproses banyak ubin: jalankan lewat QgsTask seperti pada skrip 3.1.
- [ArcGIS Pro / ArcMap] Skrip batch gagal membaca band: periksa nama band raster multi-band (misalnya Band_1 dan Band_2) dan urutannya. [CEK]
- [ArcMap] ArcMap tidak merespons saat batch: jalankan skrip dari luar ArcMap. [CEK]
#Tabel Perbandingan Bab 3: QGIS, ArcGIS Pro, dan ArcMap 10.8
Kolom Status menjelaskan seberapa pasti padanan itu. Terbukti: dokumentasi resmi sudah dibaca penulis. Kemungkinan: berdasarkan informasi umum. [CEK]: perlu dicoba di perangkat lunaknya.
| Langkah | QGIS | ArcGIS Pro | ArcMap 10.8 | Status |
|---|---|---|---|---|
| 3.1 Hitung CHM | Raster Calculator | Raster Calculator | Raster Calculator (tidak ada di ArcPy) | Terbukti: Pro dan ArcMap butuh Spatial Analyst (Pro: atau Image Analyst) |
| 3.2 Pencari puncak | Find Local Peaks | Alur: Focal Statistics (MAXIMUM) + Con + Raster to Point | Alur yang sama | Alat tunggal setara belum ditemukan; Focal Statistics dan Raster to Point terbukti |
| 3.2 Pengaturan jarak | Distance/Radius (meter) | Lingkungan Circle, radius dalam satuan peta | Lingkungan Circle, radius dalam satuan peta | Kemungkinan [CEK] |
| 3.3 Latar belakang | QgsTask | Skrip batch ArcPy; opsi paralel | Skrip batch ArcPy 2.7 dari luar ArcMap | Tidak ada padanan langsung QgsTask; opsi paralel [CEK] |
| 3.3 Daftar berkas | os.listdir | arcpy.ListRasters | arcpy.ListRasters | Kemungkinan [CEK] |
