# Pomoćni sadržaj

# Korišćeni podaci
#
# Skup podataka "Rice Image Dataset"
# - Internet sajt Murata Koklua
# - skup slika zrna pirinča
#   - godina: 2021.
#   - format podataka: JPG
# - radovi
#   - Koklu M, Cinar I, Taspinar YS. Classification of Rice Varieties with 
#     Deep Learning Methods. Computers and Electronics in Agriculture. 
#     2021;187; 106285. DOI: https://doi.org/10.1016/j.compag.2021.106285
#   - Cinar I, Koklu M. Determination of Effective and Specific Physical 
#     Features of Rice Varieties by Computer Vision in Exterior Quality 
#     Inspection. Selcuk Journal of Agriculture and Food Sciences. 2021; 
#     35(3); 229-243. DOI: https://doi.org/10.15316/SJAFS.2021.252
#   - Cinar I, Koklu M. Identification of Rice Varieties using Machine 
#     Learning Algorithms. Journal of Agricultural Sciences. 2022;28(2); 
#     307-325. DOI: https://doi.org/10.15832/ankutbd.862482
#   - Cinar I, Koklu M. Classification of Rice Varieties using Arficial 
#     Intelligence Methods. International Journal of Intelligent Systems 
#     and Applications in Engineering. 2019;7(3); 188-194. 
#     DOI: https://doi.org/10.18201/ijisae.2019355381
#
# Internet strana:
# https://www.muratkoklu.com/datasets/


# %% Biblioteke i inicijalizacija

import random
import os
import cv2

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from keras.utils.np_utils import to_categorical
from keras.models import Sequential
from keras.layers import Dense, Conv2D, MaxPooling2D, Flatten

random.seed(19)


# %% Zadatak 1

putanje_slike_vrste = {
    "Arborio": "./Rice_Image_Dataset/Arborio",
    "Basmati": "./Rice_Image_Dataset/Basmati",
    "Ipsala": "./Rice_Image_Dataset/Ipsala",
    "Jasmine": "./Rice_Image_Dataset/Jasmine",
    "Karacadag": "./Rice_Image_Dataset/Karacadag"}

vrste_broj = 5
uzorak_vrsta_obim = 100

podaci_ulazi = []
podaci_oznake = []

for vrsta, putanja in putanje_slike_vrste.items():
  datoteke_nazivi = os.listdir(putanja)
  for i in random.sample(range(len(datoteke_nazivi)), uzorak_vrsta_obim):
      putanja_slika = os.path.join(putanja, datoteke_nazivi[i])
      slika = cv2.imread(putanja_slika)
      podaci_ulazi.append(np.array(slika))
      podaci_oznake.append(vrsta)

podaci_ulazi = np.array(podaci_ulazi) / 255

kodovi_vrste_brojevi = {
    "Arborio": 0, "Basmati": 1, "Ipsala": 2, "Jasmine": 3, "Karacadag": 4}

podaci_oznake_kodirane = to_categorical(
    pd.Series(podaci_oznake).replace(kodovi_vrste_brojevi), vrste_broj)


# %% Zadatak 2

knm = Sequential()

knm.add(Conv2D(filters=16, kernel_size=(5, 5), strides=(1, 1), 
               padding="valid", activation="relu", use_bias=True, 
               input_shape=(250, 250, 3)))

knm.add(MaxPooling2D(pool_size=(2, 2)))

knm.add(Conv2D(filters=16, kernel_size=(5, 5), strides=(1, 1), 
               padding="valid", activation="relu", use_bias=True))

knm.add(MaxPooling2D(pool_size=(2, 2)))

knm.add(Flatten())

knm.add(Dense(5, activation="softmax"))

knm.summary()


# %% Zadatak 3

udeo_obuka = 0.8
izbor_obuka = [i for i in random.sample(range(len(podaci_ulazi)), 
                                        int(udeo_obuka * 
                                            podaci_ulazi.shape[0]))]

indeksi_obuka = np.repeat(False, len(podaci_ulazi))
indeksi_obuka[izbor_obuka] = True
indeksi_test = np.logical_not(indeksi_obuka)

podaci_ulazi_obuka = podaci_ulazi[indeksi_obuka]
podaci_ulazi_test = podaci_ulazi[indeksi_test]

podaci_oznake_kodirane_obuka = podaci_oznake_kodirane[indeksi_obuka]
podaci_oznake_kodirane_test = podaci_oznake_kodirane[indeksi_test]


# %% Zadatak 4

broj_epoha = 3
obim_grupe = 50

knm.compile(loss="categorical_crossentropy", optimizer="adam", 
            metrics=["accuracy"])

info = knm.fit(podaci_ulazi_obuka, podaci_oznake_kodirane_obuka,
               batch_size=obim_grupe, epochs=broj_epoha)

plt.figure()
plt.plot(info.epoch, info.history["accuracy"], "o:")
plt.ylim(0)
plt.xlabel("Epoha")
plt.ylabel("Tačnost")
plt.title("Performanse tokom obučavanja")


# %% Zadatak 5

ev = knm.evaluate(podaci_ulazi_test, podaci_oznake_kodirane_test)
print("Performanse nad podacima za testiranje:")
for i in range(len(knm.metrics_names)):
    print("[{}] {:.3f}".format(knm.metrics_names[i], ev[i]))


# %% Zadatak 6

broj_primer = 10

izbor_primer = random.sample(range(len(podaci_ulazi_test)), broj_primer)
primer_procena = knm.predict(podaci_ulazi_test[izbor_primer])
primer_oznake_procena = np.argmax(primer_procena, axis=1)
primer_oznake_stvarno = np.argmax(podaci_oznake_kodirane_test[izbor_primer], 
                                  axis=1)

kodovi_brojevi_vrste = {
    0: "Arborio", 1: "Basmati", 2: "Ipsala", 3: "Jasmine", 4: "Karacadag"}

font_ispravno = {"color": "green"}
font_neispravno = {"color": "red"}

for i in range(len(izbor_primer)):
    indeks = izbor_primer[i]
    oznaka_stvarno = kodovi_brojevi_vrste[primer_oznake_stvarno[i]]
    oznaka_procena = kodovi_brojevi_vrste[primer_oznake_procena[i]]
    plt.figure()
    plt.imshow(podaci_ulazi_test[indeks])
    plt.xticks([])
    plt.yticks([])
    plt.title("Slika {} iz test skupa".format(indeks) + "\n" + 
              "Vrsta pirinča \"{}\"".format(oznaka_stvarno) + "\n" + 
              "Procena \"{}\"".format(oznaka_procena),
              fontdict=font_ispravno if oznaka_stvarno == oznaka_procena else 
              font_neispravno)
    

# %% Zadatak 7

# dodatno eksperimentisati s podacima i neuronskom mrežom

