Given a pair of Sentinel-2 tiles — RGB (B4-B3-B2) and SWIR (B12-B8-B4) — covering a 5km × 5km agricultural area, the model outputs a structured JSON burn assessment. It was trained on 1,098 labelled image pairs and evaluated against the base model on 178 held-out test tiles.
Evaluated on 178 clear-sky test tiles (held-out split of
crop-burn-detection-labeled).
The base model produces syntactically valid JSON on every sample but collapses severity predictions to a single dominant class and outputs 0% accuracy on smoke visibility and image quality fields. Fine-tuning on domain-specific Sentinel-2 pairs corrects the severity distribution and fully unlocks the smoke and quality heads.
1{
2 "burn_detected": true,
3 "burn_severity": "moderate",
4 "active_smoke_visible": false,
5 "vegetation_phase": "post_harvest",
6 "image_quality_limited": false
7}
1from transformers import AutoProcessor, AutoModelForImageTextToText
2from PIL import Image
3import torch, json
4
5model = AutoModelForImageTextToText.from_pretrained(
6 "munish0838/crop-burn-detector-v2",
7 torch_dtype=torch.bfloat16,
8 device_map="auto",
9 trust_remote_code=True,
10)
11processor = AutoProcessor.from_pretrained(
12 "munish0838/crop-burn-detector-v2",
13 trust_remote_code=True,
14)
15
16rgb_image = Image.open("tile_rgb.png") # Sentinel-2 B4-B3-B2 composite
17swir_image = Image.open("tile_swir.png") # Sentinel-2 B12-B8-B4 composite
18
19SYSTEM_PROMPT = (
20 "You are an expert in analyzing Sentinel-2 satellite imagery for crop residue "
21 "burning detection in northern India. You analyze pairs of RGB and SWIR composites "
22 "of 5km tiles and produce structured JSON assessments."
23)
24
25USER_PROMPT = """The following two images show the same 5km × 5km tile of agricultural land.
26
27Image 1 is the RGB composite (B4-B3-B2, natural color).
28Image 2 is the SWIR composite (B12-B8-B4 false color), which highlights vegetation moisture, burn scars, and active fires.
29
30In the SWIR composite:
31 - Bright green = healthy standing crop (high NIR)
32 - Brownish / pinkish-brown = harvested stubble or bare soil
33 - Charcoal black or dark brownish-red with rectangular edges = burn scars
34 - White or bright cyan = cloud cover
35
36Analyze both images and output exactly this JSON with no additional text:
37
38{
39 "burn_detected": <true|false>,
40 "burn_severity": <"none"|"low"|"moderate"|"high">,
41 "active_smoke_visible": <true|false>,
42 "vegetation_phase": <"pre_harvest"|"harvest_in_progress"|"post_harvest"|"fallow">,
43 "image_quality_limited": <true|false>
44}"""
45
46messages = [
47 {"role": "system", "content": SYSTEM_PROMPT},
48 {"role": "user", "content": [
49 {"type": "image", "image": rgb_image},
50 {"type": "image", "image": swir_image},
51 {"type": "text", "text": USER_PROMPT},
52 ]},
53]
54
55inputs = processor.apply_chat_template(
56 messages,
57 add_generation_prompt=True,
58 return_tensors="pt",
59 return_dict=True,
60 tokenize=True,
61).to(model.device)
62
63with torch.no_grad():
64 out = model.generate(**inputs, max_new_tokens=256, do_sample=False)
65
66input_len = inputs["input_ids"].shape[1]
67new_tokens = out[:, input_len:]
68raw = processor.batch_decode(new_tokens, skip_special_tokens=True)[0].strip()
69
70result = json.loads(raw)
71print(result)
72# {'burn_detected': True, 'burn_severity': 'moderate', 'active_smoke_visible': False,
73# 'vegetation_phase': 'post_harvest', 'image_quality_limited': False}
Official Indian government fire monitoring relies on VIIRS and MODIS satellites that pass at fixed times (10:30 AM, 1:30 PM). By 2025, over 90% of large crop fires in Punjab were being lit after 3 PM — after every government satellite had passed. A 2025 CEEW field study found 169 burnt fields in a single district over two days; the government's system detected 7.
Sentinel-2 burn scars persist for days after a fire. This model reads those scars — alongside live NASA FIRMS hotspots — to give enforcement teams a complete picture regardless of when the fire happened.
This is part of
Parali, a real-time crop burn detection platform for northern India.