01 - Wprowadzenie
Przetwarzanie i Analiza Obrazów
Politechnika Poznańska, Instytut Robotyki i Inteligencji Maszynowej
Ćwiczenie laboratoryjne 1: Python i biblioteki - przypomnienie
Powrót do spisu treści ćwiczeń laboratoryjnych
W tym ćwiczeniu: - Poznajemy język programowania Python oraz jego składnię. - Zapoznajemy się z podstawowymi funkcjami i metodami wbudowanymi w Pythonie. - Wprowadzamy biblioteki OpenCV i NumPy, które będą kluczowe dla pracy z obrazami w kolejnych ćwiczeniach.
Wstęp - język programowania Python
Na zajęciach wykorzystywać będziemy język programowania Python oraz biblioteki dedykowane przetwarzaniu obrazów oraz – w mniejszym stopniu – uczeniu maszynowemu.
Python to język programowania wysokiego poziomu ogólnego przeznaczenia, o rozbudowanym pakiecie bibliotek standardowych, którego ideą przewodnią jest czytelność i klarowność kodu źródłowego. Jego składnia cechuje się przejrzystością i zwięzłością. Python wspiera różne paradygmaty programowania: obiektowy, imperatywny oraz w mniejszym stopniu funkcyjny. Posiada w pełni dynamiczny system typów i automatyczne zarządzanie pamięcią, będąc w tym podobnym do języków Perl, Ruby, Scheme czy Tcl. Podobnie jak inne języki dynamiczne jest często używany jako język skryptowy. Interpretery Pythona są dostępne na wiele systemów operacyjnych. Python rozwijany jest jako projekt Open Source zarządzany przez Python Software Foundation, która jest organizacją non-profit. Standardową implementacją języka jest CPython (napisany w C), ale istnieją też inne. (źródło: Wikipedia)
Skrypty pythonowe
Skrypty pythonowe to pliki tekstowe zawierające kod źródłowy napisany
w języku Python. Skrypty te mogą być uruchamiane bezpośrednio przez
interpreter Pythona, co pozwala na wykonywanie różnych zadań, takich jak
automatyzacja, analiza danych, tworzenie aplikacji webowych, czy też
przetwarzanie obrazów. Skrypty pythonowe mają rozszerzenie
.py i mogą być tworzone i edytowane za pomocą dowolnego
edytora tekstu lub zintegrowanego środowiska programistycznego (IDE).
Aby uruchomić skrypt pythonowy, wystarczy użyć polecenia
python nazwa_skryptu.py w terminalu lub wierszu poleceń,
pod warunkiem, że Python jest zainstalowany i skonfigurowany na danym
systemie. Skrypty pythonowe są szeroko stosowane w różnych dziedzinach,
od nauki danych po tworzenie gier, i stanowią podstawę dla wielu
projektów programistycznych.
Wybór środowiska programistycznego
PyCharm - zintegrowane środowisko programistyczne (IDE) stworzone przez firmę JetBrains, które będziemy domyślnie wykorzystywać na zajęciach. PyCharm oferuje wiele funkcji, takich jak inteligentne podpowiedzi kodu, refaktoryzacja, debugowanie, integracja z systemami kontroli wersji i wiele innych, co czyni go popularnym wyborem wśród programistów Pythona. Wersja Community jest darmowa i open-source.
VS Code - Visual Studio Code to lekki, ale potężny edytor kodu źródłowego opracowany przez Microsoft. Jest darmowy i open-source, oferując szeroką gamę rozszerzeń, które umożliwiają programowanie w różnych językach, w tym Pythonie. VS Code jest ceniony za swoją szybkość, elastyczność i wsparcie dla wielu platform.
Jupyter Notebook - Jupyter Notebook to interaktywne środowisko programistyczne, które pozwala na tworzenie i udostępnianie dokumentów zawierających kod źródłowy, równania, wizualizacje i tekst narracyjny. Jest szczególnie popularny wśród naukowców danych i badaczy, ponieważ umożliwia łatwe eksperymentowanie z kodem i prezentowanie wyników w sposób czytelny i interaktywny.
💥 Zadanie do wykonania 💥
Otwórz wybrany edytor kodu i utwórz nowy plik o nazwie
main.py. Następnie wpisz poniższy kod:
print("Witaj w świecie przetwarzania i analizy obrazów!")Zapisz plik i uruchom go, aby zobaczyć efekt działania.
Składnia języka Python
Składnia języka Python jest prosta i czytelna, co czyni go łatwym do nauki dla początkujących programistów. Oto kilka podstawowych elementów składni Pythona:
- Komentarze: W Pythonie komentarze rozpoczynają się
od znaku
#i są ignorowane przez interpreter. Służą do wyjaśniania kodu lub dodawania notatek dla programisty.
# To jest komentarz w Pythonie- Zmienne: W Pythonie nie trzeba deklarować typu zmiennej, wystarczy przypisać jej wartość.
x = 10
y = "Hello, World!"
z = 3.14- Funkcje: Funkcje w Pythonie definiuje się za pomocą
słowa kluczowego
def, a ich ciało jest wcięte.
def greet(name):
return f"Hello, {name}!"- Pętle: Python obsługuje pętle
foriwhiledo iteracji.
# Pętla for (iteracja po zakresie)
for i in range(5):
print(i)
# Pętla for (iteracja po liście)
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# Pętla while
count = 0
while count < 5:
print(count)
count += 1- Instrukcje warunkowe: Python używa instrukcji
if,elifielsedo tworzenia warunków.
age = 18
if age < 18:
print("Niepełnoletni")
elif age == 18:
print("Pełnoletni")
else:
print("Dorosły")- Importowanie bibliotek: Aby korzystać z funkcji i klas dostępnych w bibliotekach, należy je zaimportować.
import numpy as np # Importowanie biblioteki NumPy do obliczeń numerycznych
import cv2 # Importowanie biblioteki OpenCV do przetwarzania obrazów- Bloki kodu: W Pythonie bloki kodu są definiowane przez wcięcia. Zazwyczaj używa się czterech spacji do wcięcia (lub tabulatora, który jest równoważny czterem spacji).
def example_function():
print("To jest blok kodu wewnątrz funkcji.")
if True:
print("To jest blok kodu wewnątrz instrukcji warunkowej.")- Listy, krotki i słowniki: Python oferuje różne struktury danych do przechowywania kolekcji elementów.
# Lista - mutowalna, uporządkowana kolekcja elementów
my_list = [1, 2, 3, 4, 5]
# Krotka - niemutowalna, uporządkowana kolekcja elementów
my_tuple = (1, 2, 3, 4, 5)
# Słownik - mutowalna, nieuporządkowana kolekcja par klucz-wartość
my_dict = {"name": "Alice", "age": 30, "city": "New York"}Wybrane metody i funkcje wbudowane
Python oferuje wiele wbudowanych funkcji, które ułatwiają pracę z danymi i kodem. Oto kilka z nich:
print(): Służy do wyświetlania informacji na ekranie.
print("Hello, World!")len(): Zwraca długość obiektu, takiego jak lista, krotka, słownik czy string.
my_list = [1, 2, 3, 4, 5]
print(len(my_list)) # Output: 5type(): Zwraca typ obiektu.
x = 10
print(type(x)) # Output: <class 'int'>range(): Generuje sekwencję liczb, często używaną w pętlach.
for i in range(5):
print(i) # Output: 0, 1, 2, 3, 4input(): Pobiera dane od użytkownika.
name = input("Podaj swoje imię: ")
print(f"Witaj, {name}!")max()imin(): Zwracają odpowiednio największy i najmniejszy element w iterowalnym obiekcie.
numbers = [1, 2, 3, 4, 5]
print(max(numbers)) # Output: 5
print(min(numbers)) # Output: 1sorted(): Zwraca posortowaną listę z iterowalnego obiektu.
numbers = [5, 2, 3, 1, 4]
print(sorted(numbers)) # Output: [1, 2, 3, 4, 5]💥 Zadanie do wykonania 💥
Napisz skrypt, który poprosi użytkownika o podanie trzech liczb, a
następnie wyświetli największą z nich. Użyj funkcji
input(), max() i print().
OpenCV - biblioteka do przetwarzania obrazów
Na tych zajęciach będziemy korzystać z biblioteki OpenCV (Open Source Computer Vision Library), która jest jedną z najpopularniejszych bibliotek do przetwarzania obrazów i analizy wideo. OpenCV oferuje szeroki zakres funkcji do manipulacji obrazami, detekcji obiektów, rozpoznawania twarzy, analizy ruchu i wielu innych zastosowań związanych z wizją komputerową. Jej naukę zaczniemy na kolejnym ćwiczeniu, a tym czasem skupimy się na poznaniu biblioteki NumPy, która jest kluczowa dla pracy z obrazami w Pythonie.
NumPy - podstawowa biblioteka do obliczeń numerycznych
NumPy (Numerical Python) to podstawowa biblioteka Pythona do obliczeń numerycznych. Oferuje ona potężne narzędzia do pracy z dużymi, wielowymiarowymi tablicami i macierzami danych, a także funkcje matematyczne do operacji na tych strukturach.
Bibliotkę tę można zaimportować za pomocą polecenia:
import numpy as np # Importowanie biblioteki NumPy i nadanie jej aliasu 'np' - jest to powszechnie stosowana konwencja w społeczności Pythona.Uwaga:
Obrazy cyfrowe są często reprezentowane jako tablice numeryczne, gdzie każdy element tablicy odpowiada wartości piksela. Dlatego znajomość biblioteki NumPy jest kluczowa dla przetwarzania i analizy obrazów.
Jak stworzyć tablicę NumPy?
Tablice (macierze, wektory, tensory) w NumPy można tworzyć na wiele sposobów, w zależności od potrzeb. Oto kilka podstawowych metod tworzenia tablic NumPy:
# Tworzenie tablicy NumPy z listy
my_list = [1, 2, 3, 4, 5]
my_array = np.array(my_list)
print(my_array) # Output: [1 2 3 4 5]
# Tworzenie tablicy NumPy z listy list (2D)
my_2d_list = [[1, 2, 3], [4, 5, 6]]
my_2d_array = np.array(my_2d_list)
print(my_2d_array)
# Output:
# [[1 2 3]
# [4 5 6]]
# Tworzenie tablicy NumPy z zakresu liczb
my_range_array = np.arange(0, 10, 2) # Tworzy tablicę z liczbami od 0 do 10 z krokiem 2
print(my_range_array) # Output: [0 2 4 6 8]
# Tworzenie tablicy NumPy wypełnionej zerami
zeros_array = np.zeros((3, 3)) # Tworzy tablicę 3x3 wypełnioną zerami
print(zeros_array)
# Output:
# [[0. 0. 0.]
# [0. 0. 0.]
# [0. 0. 0.]]
# Tworzenie tablicy NumPy wypełnionej wybranym wartością
full_array = np.full((2, 4), 7) # Tworzy tablicę 2x4 wypełnioną wartością 7
print(full_array)
# Output:
# [[7 7 7 7]
# [7 7 7 7]]Typy danych w tablicach NumPy
Tablice NumPy mogą przechowywać różne typy danych, takie jak liczby
całkowite, liczby zmiennoprzecinkowe, liczby zespolone, a także dane
tekstowe. Domyślnie, NumPy dla liczb całkowitych używa typu
int64, a dla liczb zmiennoprzecinkowych typu
float64. Można jednak określić inny typ danych podczas
tworzenia tablicy lub zmienić go później. Typ danych w tablicy NumPy
można sprawdzić za pomocą atrybutu dtype, oto kilka
przykładów:
print(np.array([1, 2, 3]).dtype) # Output: int64
print(np.array([1.0, 2.0, 3.0]).dtype) # Output: float64
print(np.array(['abc', 'abc', 'abc']).dtype) # Output: <U3 (Unicode string of length 3)>Typ danych można również określić podczas tworzenia tablicy
korzystając z argumentu dtype:
my_array = np.array([1, 2, 3], dtype=np.float32)
print(my_array) # Output: [1. 2. 3.]
print(my_array.dtype) # Output: float32
my_array = np.array([1.0, 2.0, 3.0], dtype=np.int32)
print(my_array) # Output: [1 2 3]
print(my_array.dtype) # Output: int32Uwaga:
Wybór odpowiedniego typu danych jest ważny, ponieważ wpływa na zużycie pamięci i wydajność operacji na tablicach. Na przykład, jeśli potrzebujesz przechowywać tylko liczby całkowite w zakresie od 0 do 255 (np. wartości pikseli obrazu), możesz użyć typunp.uint8, który jest domyślnie używany do reprezentacji obrazów w OpenCV.
Podstawowe operacje na tablicach NumPy
NumPy oferuje szeroki zakres operacji na tablicach, które są zoptymalizowane pod kątem wydajności. Oto kilka podstawowych operacji, które można wykonywać na tablicach NumPy:
# Tworzenie dwóch tablic NumPy
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# Rozmiar tablicy
print(a.shape) # Output: (3,)
# Dodawanie tablic
c = a + b
print(c) # Output: [5 7 9]
# Mnożenie tablic (element-wise)
d = a * b
print(d) # Output: [ 4 10 18]
# Dzielenie tablic (element-wise)
e = b / a
print(e) # Output: [4. 2.5 2.]
# Potęgowanie tablic (element-wise)
f = a ** 2
print(f) # Output: [1 4 9]
# Operacje na macierzach (dot product)
g = np.dot(a, b)
print(g) # Output: 32 (1*4 + 2*5 + 3*6)
# Transpozycja macierzy
h = np.array([[1, 2], [3, 4]])
print(h.T)
# Output:
# [[1 3]
# [2 4]]
# Agregacja danych (np. suma, średnia)
print(np.sum(a)) # Output: 6
print(np.mean(a)) # Output: 2.0
print(np.max(a)) # Output: 3
print(np.min(a)) # Output: 1Indeksowanie i slicing tablic NumPy
Indeksowanie i slicing w NumPy pozwala na dostęp do poszczególnych elementów, wierszy, kolumn lub podtablic w tablicy. Oto kilka przykładów:
# Tworzenie tablicy 2D
my_array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# Sprawdzenie kształtu tablicy
print(my_array.shape) # Output: (3, 3)
# Indeksowanie pojedynczego elementu
print(my_array[0, 1]) # Output: 2 (element w pierwszym wierszu, drugiej kolumnie)
# Indeksowanie całego wiersza
print(my_array[1]) # Output: [4 5 6] (drugi wiersz)
# Indeksowanie całej kolumny
print(my_array[:, 2]) # Output: [3 6 9] (trzecia kolumna)
# Slicing (wycinanie) podtablicy
print(my_array[0:2, 1:3])
# Output:
# [[2 3]
# [5 6]] Operacje logiczne i maskowanie tablic NumPy
NumPy umożliwia wykonywanie operacji logicznych na tablicach, co pozwala na tworzenie masek i filtrowanie danych. Oto kilka przykładów:
# Tworzenie tablicy NumPy
my_array = np.full((3, 3), 5, dtype=np.int32) # Tworzy tablicę 3x3 wypełnioną wartością 5
# Wpiszmy do tablicy kilka innych wartości
my_array[0, 0] = 1
my_array[1, 1] = 2
my_array[2, 2] = 3
print(my_array)
# Output:
# [[1 5 5]
# [5 2 5]
# [5 5 3]]
# Tworzenie maski logicznej (np. elementy większe niż 4)
mask = my_array > 4
print(mask)
# Output:
# [[False True True]
# [ True False True]
# [ True True False]]
# Filtrowanie danych za pomocą maski, np. zerowanie elementów mniejszych lub równych 4
filtered_array = np.where(mask, my_array, 0)
print(filtered_array)
# Output:
# [[0 5 5]
# [5 0 5]
# [5 5 0]]Uwaga:
Operacje logiczne i maskowanie są szczególnie przydatne w przetwarzaniu obrazów, gdzie można łatwo filtrować piksele na podstawie ich wartości lub innych kryteriów, co jest kluczowe dla wielu algorytmów analizy obrazów. Jednocześnie, korzystanie z wbudowanych funkcji NumPy do operacji na tablicach jest znacznie bardziej wydajne niż ręczne iterowanie po elementach, co jest ważne przy pracy z dużymi obrazami.
💥 Zadanie do wykonania 💥
Napisz skrypt, który tworzy tablicę NumPy o wymiarach 5x5 wypełnioną wybranymi przez Ciebie wartościami. Następnie stwórz maskę logiczną, która zaznaczy elementy większe niż 10, i użyj tej maski do stworzenia nowej tablicy, w której elementy większe niż 10 pozostaną bez zmian, a pozostałe zostaną zastąpione zerami. Wyświetl obie tablice: oryginalną i przefiltrowaną.
💥 Zadanie do wykonania 💥
Mając listę średnich temperatur z ostatniego tygodnia:
[20, 22, 19, 24, 21, 18, 23], użyj funkcji NumPy do
obliczenia średniej temperatury, Następnie przelicz podaną temperaturę
na skalę Fahrenheita i wyświetl wynik. (Wzór do przeliczenia:
F = (C * 9/5) + 32).