Binarization#

0. Import package#

[1]:
%matplotlib inline

import cv2
import collections

import openalea.phenomenal.image as phm_img
import openalea.phenomenal.data as phm_data
import openalea.phenomenal.display as phm_display
from openalea.phenotyping_data.fetch import fetch_all_data

1. Prerequisites#

1. Load images#

Here, we load all the image of the dataset to simply the toturial, commodly you load just the images you want process one after the other.

[2]:
data_dir = fetch_all_data("plant_6/raw").parent
raw_images = phm_data.raw_images(data_dir)
Downloading file 'plant_6/raw/side/0.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/side/0.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/raw/side/120.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/side/120.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/raw/side/150.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/side/150.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/raw/side/180.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/side/180.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/raw/side/210.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/side/210.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/raw/side/240.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/side/240.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/raw/side/270.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/side/270.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/raw/side/30.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/side/30.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/raw/side/300.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/side/300.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/raw/side/330.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/side/330.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/raw/side/60.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/side/60.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/raw/side/90.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/side/90.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/raw/top/0.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/raw/top/0.png' to '/home/docs/.cache/phenotyping_data'.

1.3. Display images#

You can view each image according to this date and angle of view like this : Note : Angle top view is represented by negative number (-1)

[3]:
phm_display.show_images(
    [raw_images["side"][120], raw_images["side"][30], raw_images["top"][0]]
)
../_images/examples_Binarization_5_0.png

2. Binarization#

2.1. Define a binarization routines#

[4]:
masks=fetch_all_data("plant_6/mask")
Downloading file 'plant_6/mask/mask_hsv.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/mask/mask_hsv.png' to '/home/docs/.cache/phenotyping_data'.
Downloading file 'plant_6/mask/mask_mean_shift.png' from 'https://raw.githubusercontent.com/openalea/phenotyping_data/main/data/plant_6/mask/mask_mean_shift.png' to '/home/docs/.cache/phenotyping_data'.
[5]:
def routine_side_binarization(image, mean_img):
    maks = phm_data.tutorial_data_binarization_mask(data_dir)

    threshold = 0.3
    dark_background = False

    hsv_min = (30, 11, 0)
    hsv_max = (129, 254, 141)

    # Convert image on HSV representation
    hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    # Threshold the image with HSV min and max value
    binary_hsv_image = phm_img.threshold_hsv(hsv_image, hsv_min, hsv_max, maks[0])

    # Threshold the image with difference between image and mean_image
    binary_mean_shift_image = phm_img.threshold_meanshift(
        image, mean_img, threshold, dark_background, maks[1]
    )

    # Add the two image
    result = cv2.add(binary_hsv_image, binary_mean_shift_image)

    # Erode and dilate the image to remove possible noise
    result = cv2.medianBlur(result, 3)

    return result


def routine_top_binarization(image):
    hsv_min = (42, 75, 28)
    hsv_max = (80, 250, 134)
    median_blur_size = 9
    iterations = 5

    # Convert image on HSV representation
    hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    # Apply a median blur on the image
    hsv_image = cv2.medianBlur(hsv_image, ksize=median_blur_size)

    # Threshold the image with HSV min and max value
    bin_img = phm_img.threshold_hsv(hsv_image, hsv_min, hsv_max)
    # dilate and erode the image to remove possible noise
    bin_img = phm_img.dilate_erode(bin_img, kernel_shape=(3, 3), iterations=iterations)

    return bin_img

2.2. Binarize images#

[6]:
# Compute the mean image of the side view image

mean_img = phm_img.mean_image(list(raw_images["side"].values()))

routine_binarization = {
    "side": lambda im: routine_side_binarization(im, mean_img),
    "top": lambda im: routine_top_binarization(im),
}

bin_images = collections.defaultdict(dict)
for id_camera in raw_images:
    for angle in raw_images[id_camera]:
        bin_images[id_camera][angle] = routine_binarization[id_camera](
            raw_images[id_camera][angle]
        )

2.3. Display images binarize#

[7]:
id_camera, angle = "side", 120
phm_display.show_images(
    [raw_images[id_camera][angle], mean_img, bin_images[id_camera][angle]]
)
../_images/examples_Binarization_12_0.png
[8]:
id_camera, angle = "top", 0
phm_display.show_images([raw_images[id_camera][angle], bin_images[id_camera][angle]])
../_images/examples_Binarization_13_0.png