Projekt 1

Opis projektu

Zadanie

Zadanie polega na uzupełnieniu funkcjonalności pakietu jpeg, który pozwala na wczytywanie i zapisywanie obrazów w formacie JPEG. Pakiet ten zawiera dwie funkcje, do wczytywania i zapisywania obrazów we wspomnianym formacie. Zadanie polega na napisaniu trzech prostych funkcji:

  • funkcji plotJPEG(), która pozwala łatwo wyświetlić wczytany obraz;
  • funkcji convertToGray(), która pozwala skonwertować wczytany obraz do odcieniu szarości wykorzystując dwie metody (metodę średniej i średniej ważonej);
  • funkcji binarize(), która pozwala na binaryzację obrazu (wykorzystując algorytm globalnej binaryzacji).

Poniżej znajdują się dokładne opisy funkcjonalności wspomnianych powyżej funkcji oraz typowe przykłady, które należy zamieścić w przesłanym rozwiązaniu.

W pierwszej kolejności chcemy wczytać przykładowy obraz w formacie JPEG.

### Wczytanie przykładowego obrazu
i1 <- readJPEG(source = "./cat1.jpeg")

W następnej kolejności chcemy wyświetlić wczytany wykres.

plotJPEG( img = i1)

Wynik wyświetlenia wczytanego obrazu jest pokazany poniżej.

win1.png

Figure 1: Wczytany obraz

Funkcja do wyświetlania obrazu powinna być zaimplementowana w taki sposób aby wyświetlany obraz nie był przeskalowany, w szczególności, nawet po manualnym rozciągnięciu okna obraz nie powinien zachowywać stosunek długości boków (aspect ratio). Poniższy rysunek pokazuje taką sytuację. Należy zwrócić uwagę, że wczytany obraz jest nadal wyświetlany poprawnie.

win2.png

Figure 2: Wczytany obraz zachowuje stosunek długości boków nawet po przeskalowaniu okienka

W następnej kolejności chcemy dokonać konwersji z obrazu kolorowego (zakładamy, że obraz jest zapisany w przestrzeni RGB) do obrazu w odcieniach szarości. Dwie typowe konwersje, które mają tutaj zastosowanie to konwersja średnia i konwersja ważona (luminosity conversion). W przypadku pierwszej metody poziom szarości dla danego piksela oblicza się zgodnie ze wzorem \[ gray = \frac{r + g + b}{3}, \] gdzie \( r, g, b \) to wartości dla barw czerwonej, zielonej i niebieskiej. W przypadku konwersji ważonej używa się wag odpowiadającym częstotliwościom barw co sprowadza się do następującego wzoru \[ gray = 0.299 \cdot r + 0.587 \cdot g + 0.114 \cdot b. \]

Konwersja z obrazu kolorowego do obrazu w odcieniach szarości powinno być zaimplementowana w funkcji convertToGray(). Typowe zastosowanie tej funkcji powinno wyglądać w następujący sposób.

### Metoda domyślna wykorzystuje metodę ważoną
plotJPEG(convertToGray(i1))
dev.copy( device = png, "./gray1.png")
dev.off()

### Można również wykorzystać metodę prostej średniej
plotJPEG(convertToGray(i1, method = "average"))
dev.copy( device = png, "./gray2.png")
dev.off()

W powyższym przykładzie należy zignorować fragmenty związane z zapisywaniem uzyskanych wykresów do pliku. Fragmenty zostały wykorzystane tylko aby w opisie można było pokazać działanie i różnice pomiędzy metodami konwersji. Wyniki konwersji metodą ważoną są pokazane poniżej.

gray1.png

Figure 3: Metoda ważona konwersji

gray2.png

Figure 4: Metoda prostej średniej

Ostatecznie należy również zaimplementować metodę binaryzacji obrazu. Binaryzacja obrazu polega na konwersji obrazu tylko do dwóch kolorów: białego i czarnego. Istnieje wiele algorytmów wykonywania takiej konwersji, które generalnie można podzielić na algorytmy globalne i lokalne. W zadaniu należy zaimplementować jedynie algorytm globalny. Algorytm ten polega na konwersji obrazu do odcieni szarości a następnie wszystkich pikselom, którym przypisana jest wartości poniżej pewnego poziomu przypisuje się kolor czarny a pozostałym kolor biały. Poziom odcięcia może być ustalany różnie. W zadaniu należy zaimplementować trzy możliwości: ustawienie manualne, wartość średnią i medianę. Poniżej jest przykładowy kod.

### Domyślnie wykorzystywana jest wartość średnia
plotJPEG(binarize(img = convertToGray(img = i1)))
dev.copy( device = png, "./bin1.png")
dev.off()

### Można wykorzystać medianę
plotJPEG(binarize(img = convertToGray(img = i1), threshold = "median"))
dev.copy( device = png, "./bin2.png")
dev.off()

### Można wykorzystać arbitralną wartość
plotJPEG(binarize(img = convertToGray(img = i1), threshold = .35))
dev.copy( device = png, "./bin3.png")
dev.off()

Uzyskane wyniki są przedstawione poniżej.

bin1.png

Figure 5: Binaryzacja obrazu, punkt odcięcia jest wartością średnią

bin2.png

Figure 6: Binaryzacja obrazu, punkt odcięcia jest medianą

bin3.png

Figure 7: Binaryzacja obrazu z podaną wartością

Z technicznego punktu widzenia warto zauważyć, że argument threshold posiada wartość domyślną ale może przyjmować zarówno string jak i wartość liczbową.

Techniczne warunki zaliczenie

Zadanie powinno być rozwiązane w pojedynczym skrypcie w pliku R. Rozwiązanie powinno zawierać definicje trzech funkcji a następnie przykładowe wykorzystanie zaproponowanych funkcji. Rozwiązania bez przykładów nie będą zaliczane. W rozwiązaniu nie wolno wykorzystywać dodatkowych pakietów poza pakietem jpeg. Jedynie dozwolone symbole to ASCII.

Data: 2021-04-06 Tue 00:00

Autor: Michał Ramsza

Created: 2021-04-06 Tue 18:38

Validate