Komunikacja Człowiek-Komputer (2011)

Komunikacja Człowiek-Komputer

Zadania

Gradienty

Napisz program, który wyświetli kilka poziomych prostokątów wypełnionych różnymi gradientami. Gradienty:

  1. (RGB) biały->czarny
  2. (RGB) od niebieskiego, przez zielony po czerwony (najkrótszą ścieżką)
  3. (RGB) od niebieskiego, przez zielony po czerwony (pełny)
  4. (RGB) od czarnego do białego przez wszystkie kolory (dowolnie)
  5. (HSI) biały->czarny
  6. (HSI) od niebieskiego, przez zielony po czerwony (pełny). Jeśli gradient ten wygląda inaczej niż “pełny” gradient RGB, to prawdopodobnie musisz poprawić gradient RGB
  7. (HSI) dowolny (ciekawy) gradient

Każdy gradient ma implementować interfejs (lub, jeśli język nie ma interfejsów, dziedziczyć z klasy abstrakcyjnej):

interface IGradient {
    Color getColor(double v); // 0<=v<=1
}

Kolorowanie mapy

Napisz program, który w czytelny dla człowieka sposób wyświetli plik z numerycznym modelem terenu. W tym celu:

  1. Wczytaj plik z danymi (*.dem). Format: Plik z danymi zawiera w pierwszej linii trzy liczby określające szerokość i wysokość mapy oraz odległość między dwoma sąsiednimi punktami na mapie w cm. W kolejnych liniach znajduje się macierz wysokości w metrach. W każdej linii jest tyle liczb, jaka jest szerokość mapy. Lini jest tyle, ile wynosi jej wysokość.
  2. Używając wybranego gradientu wyświetl wczytany teren w postaci kolorowej mapy. Przykładowy wynik: 
  3. Wygląda płasko? Dodaj więc cieniowanie, tak aby nadać rysunkowi głębi. Jak to zrobić? Można wzorować się na wzorach z tego artykułu (dostępny z sieci PP) albo postępować wg następujących kroków:
    1. Wyznacz dla każdego punktu wektor prostopadły do zbocza.
    2. Określ wektor padania światła.
    3. W zależności od kąta pomiędzy tymi wektorami rozjaśnij albo przyciemnij dany punkt (najwygodniej w modelu HSB). Przykłady:
  4. Dobierz parametry (gradient, cieniowanie), tak aby osiągnąć jak najlepszy efekt.

Tablet

  1. Na podstawie znajomości formatu napisz program wczytujący pliki binarne (zbiór1, zbiór2), opisujące przebieg kreślenia po tablecie. Dostęp do tabletu umożliwia program TrackHand.
  2. Następnie dokonaj wizualizacji przebiegu kreślenia, tak aby w czytelny i jak najbardziej precyzyjny sposób zobrazować wszystkie elementy kreślenia (np. pochylenie, siła nacisku). Możesz w tym celu wykorzystać gradienty, cienie lub inne metody.

W tym zadaniu ocenię czytelność wizualizacji i jej precyzję (0-6 punktów) oraz kreatywność (0-4 punkty), rozumianą jako niesztampowe rozwiązanie.

Parkinson cz. 1

Zadaniem jest napisanie programu, który w obiektywny sposób oceni stopień choroby Parkinsona na podstawie rysunku na tablecie. Zadanie jest realizowane w grupach dwuosobowych i przebiega w kilku etapach:

  1. Należy przejrzeć zbiór danych parkinson_set1.zip. A następnie wejść w rolę konsylium ekspertów (dwie połączone grupy): wg uznania, uporządkować rysunki zgodnie ze stopniem choroby (skala porządkowa). Następnie każdemu rysunkowi konsylium powinno przydzielić wartość z zakresu od 0 do 100, oznaczający stopień choroby, gdzie 0 oznacza brak symptomów choroby, a 100 “zaawansowaną chorobę” (skala przedziałowa).
  2. Należy wymyślić metodę, która automatycznie określi stopień zaawansowania choroby na podstawie rysunku. Niech metoda taka implementuje interfejs:
    interface ParkinsonEvaluator {
        double evaluate(Drawing drawing);
    }

    gdzie Drawing reprezentuje wczytany rysunek z tabletu.

    Metoda powinna być tak zaprojektowana, aby zwracać ten sam wynik niezależnie od rotacji lub przesunięcia rysunku.

  3. Metodę należy ocenić na zbiorze parkinson_set1.zip. Ocena metody to średnie kwadratowe odchylenie stopnia zaawansowania choroby (obliczone przez metodę) od wzorcowego stopnia zaawansowania choroby (określonego przez konsylium). Ocena metody niech implementuje interfejs:
    interface ParkinsonEvaluatorEvaluator {
      int evaluate(ParkinsonEvaluator parkinsonEvaluator);
    }
  4. Zaprojektowana metoda z pewnością ma jakieś parametry (lub ręcznie modyfikowane stałe, które powinny być, de facto, parametrami). Wszystkie parametry metody (wagi, współczynniki, etc.) należy zawrzeć w klasie <NazwaMetody>Params, np.
    class MyEvaluatorParams {
      double feature1weight;
      double feature2weight;
      int numberOfConsecutivePoints;
      [...]
    }

    Należy zapewnić, aby konstruktor metody przyjmował jako argument instancje klasy z parametrami.

  5. Parametry dobrane ręcznie nie są optymalne. Należy określić dziedziny parametrów (np. “liczba rzeczywista od 0 do 10″) i przeszukać przestrzeń parametrów, aby znaleźć najlepszy zestaw parametrów (najlepszy czyli taki, który daje najlepszą ocenę na danym zbiorze). Jak przeszukać tę przestrzeń? Można np. dokonać przeszukiwania losowego. Chętne osoby mogą zaimplementować jakiś wariant przeszukiwania lokalnego.
  6. Do przemyślenia: Jak dobra jest metoda po wykonanej optymalizacji? Czy będzie działała dobrze na innych rysunkach?

Parkinson cz. 2

  1. Należy powtórzyć konsylium z cz. 1 zadania, tym razem dla rysunków ze zbioru parkinson_set2.zip. Podczas przydzielania wartości rysunkom należy wziąć pod uwagę oceny, które konsylium przydzieliło rysunkom z parkinson_set1.zip tak, aby oceny rysunków z obu zbiorów były spójne (to samo konsylium, te sama intuicja, ta sama skala).
  2. Ile wynosi ocena metody (zoptymalizowanej dla zbioru parkinson_set1.zip) na zbiorze parkinson_set2.zip? Czy jest ona lepsza czy gorsza niż ocena dla parkinson_set1.zip? Dlaczego?
  3. Należy zaimplementować metodę “50″, czyli taką, która dla każdego rysunku zwraca wartość 50.
  4. Porównaj wyniki Twojej metoda i metody “50″ dla parkinson_set1.zip oraz  parkinson_set2.zip. Która jest lepsza?
  5. Połącz zbiory parkinson_set1.zip i parkinson_set2.zip. Ile wynosi średnia ocena metody losowej dla połączonego zbioru?
  6. Aby równocześnie skorzystać z dodatkowych danych (parkinson_set2.zip) oraz otrzymać wiarygodną ocenę metody, dla połączonych zbiorów zastosuj 10-krotną kroswalidację.
  7. Ile wynosi ocena Twojej metody po kroswalidacji. Jeśli ocena jest słaba, spróbuj poprawić metodę. Być może wybór cech był nietrafiony? Albo metoda ma zbyt dużo parametrów (przeuczenie)? Po każdej poprawce testuj swoją metodą za pomocą kroswalidacji. Jaki najlepszy wynik udało Ci się uzyskać?

Parkinson cz. 3

  1. Należy powtórzyć konsylium z cz. 1 zadania, tym razem dla rysunków ze zbioru parkinson_set3.zip. Podczas przydzielania wartości rysunkom należy wziąć pod uwagę oceny, które konsylium przydzieliło rysunkom z parkinson_set1.zip oraz parkinson_set2.zip tak, aby oceny rysunków z wszystkich zbiorów były spójne (to samo konsylium, te sama intuicja, ta sama skala).
  2. Jaki wynik osiąga Twoja metoda dla parkinson_set3.zip?
  3. Czy wyniki dla parkinson_set3.zip jest zgodny z wynikiem po kroswalidacji uzyskanym w cz. 2?

Parkinson – Raport

  • schemat raportu (-> lyx)
  • termin: 12 grudnia 2011
  • ocena: 20p (-5p za każdy rozpoczęty tydzień spóźnienia)
  • przy ocenie wezmę pod uwagę: jakość, jasność opisów, logika wniosków, metoda i pomysłowość.
  • sposób dostarczenia: mailem proszę wysłać trzy pliki:
    1. <nazwisko1nazwisko2>.lyx (raport w formacie lyx)
    2. <nazwisko1nazwisko2>.pdf (wygenerowany pdf)
    3. <nazwisko1nazwisko2>.jar (kod metody w postaci wykonywalnego archiwum jar)

 

FFT – ćwiczenia cz. 1

  1. Wykonaj w Matlabie(*) skrypt simple_fft.m.
    1. Przeanalizuj skrypt.
    2. Zmień częstotliwość próbkowania na 50Hz.
    3. Spektrum jest teraz mylące, ponieważ punkty na osi OX są kolejnymi liczbami naturalnymi, a nie Hz. Popraw skrypt, tak aby oś OX spektrum była w Hz (podpowiedź: oś OX rozpoczyna się od 0Hz, a kończy się na (prawie!) w Hz, gdzie w jest częstotliwością próbkowania). Następnie: Upewnij się, że spektrum dla 1Hz-owego sinusa wygląda teraz prawidłowo.
    4. Podpisz osie obu wykresów, używając funkcji xlabel() i ylabel().
    5. Wygeneruj spektrum dla funkcji sinus o częstotliwościach 5Hz i 21Hz. Czy rozpoznajesz te funkcje patrząc na ich spróbkowane wykresy?
    6. Porównaj spektrum funkcji sin(2*pi*t), 2*sin(2*pi*t) i 3*sin(2*pi*t). Jak zmienia się amplituda na wykresie spektrum?
    7. Ile punktów jest na wykresach przy częstotliwości próbkowania 50Hz? Nie zmieniając częstotliwości próbkowania, dwukrotnie zwiększ liczbę punktów (zmienna n). Następnie: dla sin(2*pi*t) porównaj amplitudy uzyskane w tym oraz poprzednim punkcie.
    8. Na podstawie wyników uzyskanych w dwóch poprzednich punktach przeskaluj spektrum tak, aby poprawnie wskazywało amplitudy rozważanych funkcji. Sprawdź wyniki dla kilku wybranych funkcji, częstotliwości próbkowania oraz rozważanych liczb punktów.
  2. Zwróć uwagę, że spektrum jest symetryczne (poza pierwszym elementem).
    1. Przy T=1s, w=100Hz, przeanalizuj spektrum dla
      1. sin(40*2*pi*t)
      2. sin(45*2*pi*t)
      3. sin(55*2*pi*t)
      4. sin(80*2*pi*t).
    2. Jak się nazywa twierdzenie, którego konsekwencją jest takie zachowanie się spektrum?
    3. Przy T=1s, w=100Hz, wygeneruj spektrum dla sin(50*2*pi*t).
  3. Wygeneruj spektrum dla:
    1. sin(5*pi*t), T=1s, w=100Hz. Co trzeba zwiększyć, aby, precyzyjnie określić częstotliwość tej funkcji na podstawie spektrum?
    2. sin(2*pi*t) + 2*sin(4*pi*t), T=1s, w=100Hz.
    3. sin(2*pi*t) + 0.5*randn(1,n), T=1s, w=100Hz. Czy rozpoznajesz zadaną funkcję w szumie? Zwiększaj stopniowo początkowy poziom szumu (0.5) aż spektrum nie będzie jednoznaczne.
    4. 2.3 + sin(2*pi*t), T=1s, w=100Hz. Czy amplitudy się “zgadzają”? Dlaczego? (Podpowiedź: zwróć jescze raz uwagę na “symetrię” spektrum).
    5. sin(2*pi*t) oraz sin(2*pi*t + pi/4) dla T=1s, w=20Hz. Czy informacja o fazie zniknęła? Poszukaj śladów tej informacji w tablicy, będącej wynikiem operacji x1=fft(x).
  4. Oblicz wynik ifft(fft(randn(1,1000))). Czy jakaś informacja została stracona? (Uwaga: natkniesz się na problemy numeryczne – rozwiąż je).
  5. Skoro informacja w drugiej części spektrum jest nadmiarowa, to czy można ją usunąć i odtworzyć pierwotny sygnał? Sprawdź – wykonaj fft, wyzeruj drugą połowę tablicy (Podpowiedź: przemyśl dokładnie, które elementy należy wyzerować) i wykonaj ifft.

(*) Uwagi techniczne:

  • waitforbuttonpress można usunąć (czasem przydaje się w Octavie)
  • Zamiast Matlab’a można użyć Octave’a (ale proszę przygotować się na niemiłe niespodzianki) lub SciLab’a (wtedy: pi=4*atan(1);  stem->bar)

 

FFT – ćwiczenia cz. 2

  1. Plik spots.txt zawiera wartości aktywności Słońca w kolejnych miesiącach. Wykreśl ten sygnał oraz jego spektrum. Za pomocą FFT, oblicz częstotliwość cyklu aktywności słonecznej.  Przydatne mogą być następujące polecenia:
    • spots=textread(‘spots.txt’, ‘%f’) (Matlab) lub spots=fscanfMat(‘spots.txt’) (Scilab);
    • find()
  2. Proste filtrowanie. Wykreśl sygnał sin(2*pi*t) + sin(4*pi*t), T=1s, w0=20Hz. Za pomocą FFT, przekształć sygnał do dziedziny częstotliwości. Następnie usuń składowe o częstotliwości 2Hz. Tak zmodyfikowany sygnał przekształć do dziedziny czasu i wykreśl go.
  3. Informacja o fazie. Wykreśl sygnał sin(2*pi*t) + sin(4*pi*t), T=1s, w0=20Hz. Tym razem oprócz spektrum, wykreśl wykres z informacją o fazie poszczególnych częstotliwości (faza = arg(z)), gdzie z=a+bi. To samo wykonaj dla sin(2*pi*t) + cos(4*pi*t). Porównaj otrzymane wykresy.
    Przydatne będą następujące funkcje:
    • real(z)
    • imag(z)
    • atan2
  4. Wczytaj plik err.wav. Wykreśl jego spektrum w skali logarytmicznej. Określ dominujące w sygnale częstotliwości.
    Przydatne będą następujące polecenia:
    • samples=wavread(‘err.wav’)
    • samples=samples(:,1)
    • [freq,num_channels]=wavread(‘err.wav’,'size’)

FFT – ćwiczenia cz. 3

  1. Wyświetl sygnał zdefiniowany w skrypcie. Jak wygląda jego spektrum?
  2. Wyświetl sygnał f(t)=sin(2*pi*t*t), w0=100Hz, T=24s oraz jego spektrum. Przyjrzyj się wykresom. Uwaga: mnożenie “element po elemencie” wektorów wykonuje się tak: t.*t.
  3. Uruchom skrypt wykonujący analizę częstotliwościowo-czasową sygnału. Następnie:
    1. Przeanalizuj otrzymane wykresy.
    2. Przeprowadź analizę po zmianie funkcji na f(t)=sin(2*pi*t*t).
    3. Przemnóż okno przez funkcję okna Hamminga. Porównaj otrzymane wyniki z wynikami bez okna Hamminga. Czy widzisz różnicę?

Obiecane rozwiązanie zad. 3

FFT – zadanie nr 1

Korzystając z świątecznych spotkań z rodziną, nagraj 6 próbek głosów: 3 męskie i 3 damskie (nie: dzieci). Każda próbka ma zawierać krótką, max. 3-sekundową wypowiedź (proszę: bez przekleństw). Próbki mają być zapisane w nieskompresowanym formacie wav (PCM 16 bitów na próbkę). Częstotliwość próbkowania: dowolna, Liczba kanałów: dowolna, inne parametry: dowolne.

Termin: 3 stycznia (wtorek).

FFT – zadanie nr 2

Napisz program, który:

  1. Przeprowadza analizę częstotliwościowo-czasową wybranego sygnału (wav). Moc zobrazuj kolorem (z wybranego gradientu). Pliki do testów. Wymagania:
    1. Podpisane osie wykresu (co, w jakich jednostkach, kolejne wartości).
    2. Wybór szerokości okna (lista; kolejne potęgi 2-2048)
    3. Wybór funkcji okna (brak, Hamming, dwie inne wybrane)
    4. Wybór gradientu (lista).
  2. Rysuje spektrum sygnału dźwiękowego online (mikrofon). Umożliwia wybór szerokości okna i funkcji okna.

Uwaga: w programie poza standardową biblioteką Javy możesz użyć jedynie org.apache.commons.math.transform. Audio wczytaj za pomocą Java Sound API. Przykład.

Termin: 9 stycznia (przedostatnie zajęcia)

FFT – zadanie nr 3

Zadanie polega na samodzielnym napisaniu programu, który rozpoznaje płeć osoby na podstawie nagranego głosu. Szczegóły:

  • Program ma wczytać plik wav podany jako jedyny argument).
  • Zbiór treningowy
  • Program na standardowe wyjście ma wypisać dokładnie jedną linię zawierającą literę ‘K’ lub ‘M’ w zależności od rozpoznanej płci.
  • Program nie może tworzyć plików dodatkowych, czytać plikow z dysku (oprocz pliku wav i plików zawartych w archiwum jar, dostarczonych przez autora) łączyć się z siecią i robić innych złych rzeczy. Każde wykroczenie w tej materii cechujące się celowością, mające na celu złamanie reguł gry, będzie odpowiednio nagrodzone.
  • Program nie ma mieć żadnego GUI.
  • Program nie ma czekać na naciśnięcie żadnego klawisza (w szczególności klawisza enter), ponieważ nie będzie komu naciskać.
  • Pliki wav są zgodne ze standardem PCM (16 bitów na próbkę)
  • Pliki wav są nagrane w trybie mono lub stereo.
    Pliki wav mogą być nagrane z różną częstotliwością próbkowania (np. 8, 16, lub 22kHz).
  • Przykładowy programrandom.zip
  • Program musi dać odpowiedź w ciągu 5 sekund. Jeśli przekroczy ten czas, zostanie wywłaszczony.
  • Program uznaje się za zaliczony, jeśli uzyska co najmnie 65% skuteczności rozpoznawania.
  • Punktacja zgodnie ze wzorem: 0.152*exp(5.38*p), gdzie p jest skutecznoscia klasyfikacji programu (od 0 do 1). Zadanie to traktuje jako zadanie za 25 punktów, chociaz, jak widac ze wzoru, za skuteczności powyżej 95% można uzyskać sporo punktów ponad maksimum. Z przyjemnością te punkty dopiszę.
  • Program można zgłaszać wielokrotnie. Ostatecznie brane jest pod uwagę tylko ostatnie zgłoszenie. Proszę nie zostawiać tego zadania na ostatnią chwilę. Łatwo policzyć ile maksymalnie czasu sprawdzarka poświęca jednemu programowi i co będzie jeśli 30 osób zacznie próby ostatniego dnia…
  • Program ma być przygotowany w postaci wykonywalnego archiwum jar, które ma zawierać (w Eclipse opcja “Export->Runnable JAR File” + “Package required libraries into generated JAR“):
    • pliki *.class (skompilowane klasy),
    • inne potrzebne pliki, z ktorych korzysta program,
    • jar’y (w tym przypadku wolno używać jedynie commons-math-*.jar, który zawiera implementację algorytmu fft (patrz: org.apache.commons.math.transform))
    • plik README, w ktorym znajdzie sie opis metody. Plik README ma zawierać nie mniej niż 100 i nie wiecej niż 200 słów,
    • nie ma zawierać nic poza wymienionymi powyżej (w szczególności dodatkowych folderów pośrednich)
    • przyklad poprawnego archiwum: random.jar.
    • program zostanie uruchomiony poleceniem java -jar program.jar plik.wav.
    • Proszę kompilować pliki za pomocą wersji Java 1.6 lub starszej
    • Wazne: prosze o sprawdzenie, czy archiwum, a w szegolnosci program są zgodne ze specyfikacją. Przetwarzanie będzie automatyczne i nie będzie wybaczać błędów technicznych.
  • Ostateczny termin: 16 stycznia (ostatnie zajęcia)
  • Typowe problemy:
    • Archiwum jar nie jest wykonywalne.
    • Problemy z wczytywaniem plików. Dobrym testem jest ten plik
  • Gdzie wgrywać pliki? Tę informację przesłałem mailem do szefów grup.