Jelapang Padi

EfficientNet-Unet trained on https://huggingface.co/datasets/malay-huggingface/jelapang-padi

Checkpoints

All checkpoints can get at https://huggingface.co/malay-huggingface/jelapang-padi

Preparation script

All scripts and notebooks can get at https://github.com/malaysia-ai/projects/tree/master/malaysia_ai_projects/jelapang_padi

Install necessary requirements

pip3 install tensorflow>=1.15 malaya-boilerplate==0.0.15 skimage
[1]:
from malaysia_ai_projects import jelapang_padi

List available models

[2]:
jelapang_padi.available_model()
[2]:
Size (MB)
efficientnet-b4 104.0
efficientnet-b4-quantized 26.8
efficientnet-b2 57.7
efficientnet-b2-quantized 15.0

Load model

def load(model: str = 'efficientnet-b2', **kwargs):
    """
    Load Jelapang Padi model.

    Parameters
    ----------
    model : str, optional (default='efficientnet-b2')
        Model architecture supported. Allowed values:

        * ``'efficientnet-b4'`` - EfficientNet B4 + Unet.
        * ``'efficientnet-b4-quantized'`` - EfficientNet B4 + Unet with dynamic quantized.
        * ``'efficientnet-b2'`` - EfficientNet B2 + Unet.
        * ``'efficientnet-b2-quantized'`` - EfficientNet B2 + Unet with dynamic quantized.

    Returns
    -------
    result : malaysia_ai_projects.jelapang_padi.Model class
    """
[3]:
model = jelapang_padi.load()

Predict

def predict(self, inputs: List[np.array]):
    """
    Parameters
    ----------
    input: List[np.array]
        List of np.array, should be size [H, W, 3], `H` and `W` can be dynamic.

    Returns
    -------
    result: List[np.array]
    """
[4]:
from glob import glob

files = glob('example/jelapang-padi/*.png')
files
[4]:
['example/jelapang-padi/0-2183.png', 'example/jelapang-padi/1-1556.png']
[5]:
from skimage.io import imread

images = []
for f in files:
    images.append(imread(f))
[6]:
outputs = model.predict(images)
len(outputs)
[6]:
2
[7]:
import matplotlib.pyplot as plt
[8]:
plt.figure(figsize = (10, 5))
plt.subplot(1,2,1)
plt.imshow(images[0])
plt.subplot(1,2,2)
plt.imshow(outputs[0][:,:,0])
[8]:
<matplotlib.image.AxesImage at 0x166aea210>
_images/load-jelapang-padi_14_1.png
[9]:
plt.figure(figsize = (10, 5))
plt.subplot(1,2,1)
plt.imshow(images[1])
plt.subplot(1,2,2)
plt.imshow(outputs[1][:,:,0])
[9]:
<matplotlib.image.AxesImage at 0x166b9b2d0>
_images/load-jelapang-padi_15_1.png
[10]:
images[0].shape, outputs[0][:,:,0].shape
[10]:
((1024, 1024, 3), (1024, 1024))

Download satellite image using Mapbox

[11]:
# https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Tile_numbers_to_lon..2Flat.

import math
import requests
import shutil

def deg2num(lat_deg, lon_deg, zoom):
    lat_rad = math.radians(lat_deg)
    n = 2.0 ** zoom
    xtile = int((lon_deg + 180.0) / 360.0 * n)
    ytile = int((1.0 - math.asinh(math.tan(lat_rad)) / math.pi) / 2.0 * n)
    return (xtile, ytile)

def num2deg(xtile, ytile, zoom):
    n = 2.0 ** zoom
    lon_deg = xtile / n * 360.0 - 180.0
    lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
    lat_deg = math.degrees(lat_rad)
    return (lat_deg, lon_deg)

def download_img(lat, lon, zoom = 14, output_name = 'img.png'):
    x, y = deg2num(lat, lon, zoom)
    url = f'https://api.mapbox.com/styles/v1/mapbox/satellite-v9/tiles/{zoom}/{x}/{y}@2x?title=true&logo=false&access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw'
    response = requests.get(url, stream=True)
    with open(output_name, 'wb') as out_file:
        shutil.copyfileobj(response.raw, out_file)
[16]:
output_name = 'example/jelapang-padi/test.png'
download_img(lat = 5.671607, lon = 100.463231, zoom = 15, output_name = output_name)
image = imread(output_name)
[17]:
plt.imshow(image)
[17]:
<matplotlib.image.AxesImage at 0x15862dbd0>
_images/load-jelapang-padi_20_1.png
[18]:
outputs = model.predict([image])
[19]:
plt.figure(figsize = (10, 5))
plt.subplot(1,2,1)
plt.imshow(image)
plt.subplot(1,2,2)
plt.imshow(outputs[0][:,:,0])
[19]:
<matplotlib.image.AxesImage at 0x158693950>
_images/load-jelapang-padi_22_1.png

Calculate area of segmentation in km^2

pixel to meter ratio

https://wiki.openstreetmap.org/wiki/Zoom_levels,

Stile = (C ∙ cos(latitude) / (2 ^ zoomlevel)) / size image

C = 40075016.686

malaysia latitude = 3.140853

zoomlevel = 15

I just take center of malaysia latitude, to get accurate result, take the actual latitude from the satellite image.

[20]:
import math
import numpy as np

C = 40075016.686
malaysia_lat = 3.140853
per_pixel = np.abs(C * np.cos(malaysia_lat) / (2**15)) / 1024
per_pixel
[20]:
1.194328240267381

So we know 1 pixel = 1.19m,

pixel = 1.19m

pixel^2 = 1.19m * 1.19m

pixel^2 = 1.4161m^2

pixel^2 / 1.4161 = m^2

Now, get total segmentation in term of pixels,

[21]:
total_pixel = (outputs[0][:,:,0] > 0).sum()
total_pixel
[21]:
169909
[22]:
km_square = (total_pixel / (per_pixel * per_pixel)) / 1e6
km_square
[22]:
0.11911569277757181