Úvod do zpracování obrazu

Cílem dnešního cvičení je seznámit se s možnostmi zpracování obrazu na obecných úlohách. Zároveň je cílem seznámit se s typovým zadáním notebooků ze cvičení, jejich zpracováním a vytvořenou knihovnou improutils jako nástavbou nad OpenCV.

Pro připomenutí, základní pipeline zpracování obrazu se skládá z těchto kroků:

  1. Zisk obrazu
  2. Předzpracování obrazu
  3. Filtrace obrazu
  4. Segmentace obrazu
  5. Zisk informace
  6. Porovnání, další obrazové testy atd.
  7. Vizualizace výsledků

Import knihoven a konfigurace

import os
import io

import cv2
import numpy as np
import matplotlib.pyplot as plt
import pytesseract

from improutils import *

%matplotlib inline
np.set_printoptions(formatter={'float': lambda x: "{0:0.3f}".format(x)})

Úkol 1

V následujících úlohách je zapotřebí pojmenovat funkce zpracování obrazu nebo využít již existující znalosti knihovny numpy k zjištění dílčích informací o obraze.

1) Jak byste nazvali funkci pro převod obrazu vlevo na obraz vpravo?

Poznámka: ### určují místo, kde je třeba něco doplnit.

# napište název funkce namísto '...', využijte anglický jazyk
nazev_funkce = ... ###

# vypište název funkce
print(nazev_funkce)

2) Načtěte obrázek buněk neuronů z fluorescenčního mikroskopu a zobrazte jej.

img = load_image(...) ### adresa obrazu
plot_images(img)

3) Vypište pár parametrů načteného obrázku neuronů.

Využijte znalosti toho, že obrázek je v pythonu v knihovnou OpenCV reprezentován jako matice z numpy (ndarray).

resolution = ... ###
print('Rozlišení obrazu:          ' + str(resolution))

number_of_channels = ... ###
print('Počet kanálů:              ' + str(number_of_channels))

min_value = ... ###
max_value = ... ###
average_value = ...(img) ###
print('Nejnižší hodnota v obrazu: ' + str(min_value))
print('Nevyšší hodnota v obrazu:  ' + str(max_value))
print('Průměrná hodnota obrazu:   ' + str(average_value))

mpix = ... ###
print('Rozlišení v MPix:          ' + str(mpix))

4) Pohrajte si s obsahem obrazu.

Zobrazte kanál obrazu, kde se vyskytují pouze modrá jádra buněk. Dále vyřízněte pouze takovou část obrazu, aby zobrazovala právě 3 jádra.

cells = ... ###
cells3 = cells[...] ###

plot_images(cells, cells3)

5) Vytvořte pár funkcí podle algoritmů zpracování obrazu.

Vytvořte funkce:

  • Pro zisk negativu obrazu (image_negative(img)) podle algoritmu: $$ J_i = 255 - I_i $$

  • Pro zisk objektů jader (cell_objects(img, int t)) podle algoritmu: $$ J_i = \left\{ \begin{array}{ll} 255 & \text{if} & I_i \geq t;\\ 0 & \text{if} & I_i < t. \end{array} \right. $$

Kde I je vstupní obraz, J je výstupní obraz a i je každý jednotlivý pixel obrazu.

### negativ obrazu
def image_negative(img):
    # ...
    return ...

### zisk objektů
def cell_objects(img, t):
    # ...
    return ...

Funkce aplikujte na obraz se třemi jádry.

img_n = ...(cells3) ###
img_o = ...(cells3, 100) ###

plot_images(img_n, img_o)

Úkol 2

Věnujte pozornost knihovně improutils a jejím funkcím.

link = ... ###
print(link)

2) Přiřaďte jednotlivé python moduly knihovny improutils k bodům základní pipeline pro zpracování obrazu.

Poznámka: Je potřeba si aktivovat rozšíření Python markdown.

answers = {
    '1': ..., ###
    '2': ..., ###
    '3': ..., ###
    '4': ..., ###
    '5': ..., ###
    '6': ..., ###
    '7': ... ###
}
# Krok Modul(y)
1 Zisk obrazu {{ answers.get('1') }}
2 Předzpracování obrazu {{ answers.get('2') }}
3 Filtrace obrazu {{ answers.get('3') }}
4 Segmentace obrazu {{ answers.get('4') }}
5 Zisk informace {{ answers.get('5') }}
6 Porovnání, další obrazové testy atd. {{ answers.get('6') }}
7 Vizualizace výsledků {{ answers.get('7') }}

3) Vraťte se k úkolu 1.4. Kde se v balíčku improutils nachází funkce pro vyříznutí části obrázku?

Doplňte správný název a link.

name_function = ... ###
link_function = ... ###

print('Funkce `' + name_function + '` se nachází na odkazu ' + link_function)

4) Využijte nejpoužívanější funkce modulu pro zisk obrazu.

Hint: Načtěte a zobrazte obrázky log fakult ČVUT. Pro obrázky zvolte vždy vhodný název (nadpis).

imgs = []
names = [] 
for root, _, files in os.walk(...): ###
    for name in files:
        if 'logo' in name:
            ###
            imgs.append(...(os.path.join(root, name))) ###
            
...(*imgs, titles=names) ###

5) Kolik segmentačních algoritmů (funkcí) obsahuje modul pro segmentaci?

functions_seg = ... ###
print('Počet segmentačních funkcí:       ' + str(functions_seg))

6) Kde je k nalezení zdrojový kód funkce fill_holes() a kolik má vstupních parametrů?

link_fill_holes = ... ###
print(link_fill_holes)

inputs_fill_holes = ... ###
print('Počet vstupních parametrů:        ' + str(inputs_fill_holes))

7) Kde je k nalezení zdrojový kód funkce find_contours() a kolik má vstupních a výstupních parametrů?

link_find_contours = ... ###
print(link_find_contours)

inputs_find_contours = ... ###
outputs_find_contours = ... ###
print('Počet vstupních parametrů:        ' + str(inputs_find_contours))
print('Počet výstupních parametrů:       ' + str(outputs_find_contours))

8) Popište první tři vstupní a všechny výstupní parametry funkce find_contours().

Pro parametry vytvořte vždy vlastní slovník, kde klíč je název parametru a hodnota je popis parametru dle dokumentace.

inputs_description_find_contours = {
    'img_bin': ..., ###
    ...: ..., ###
    ...: ... ###
}
outputs_description_find_contours = {
    ###
}
parameters = list(inputs_description_find_contours.keys()) + list(outputs_description_find_contours.keys())
max_len = max([len(parameter) for parameter in parameters])

print("Input parameters:")
for parameter, description in inputs_description_find_contours.items():
    print('   ' + parameter.ljust(max_len) + ' - ' + description)
print()
print("Output parameters:")
for parameter, description in outputs_description_find_contours.items():
    print('   ' + parameter.ljust(max_len) + ' - ' + description)

9) Jak zjistit počty parametrů a jejich význam bez nekonečného překlikávání a hledání v repozitáři improutils?

Postup demonstrujte pro funkci find_contours().

# dopňte název funkce pro zobrazení dokumentace funkce nebo třídy
...(...) ###