#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Fri Mar 24 17:08:43 2017

@author: guido
"""

%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
from skimage import color
import skimage.filters as filters
from skimage.transform import hough_circle
from skimage.feature import peak_local_max 
from skimage import feature
from skimage import morphology
from skimage.draw import circle_perimeter
from skimage import img_as_float, img_as_ubyte
from skimage import segmentation as seg
from skimage.morphology import watershed
from scipy import ndimage as nd
from scipy.ndimage import convolve

from skimage import feature
from sklearn.model_selection import train_test_split
from skimage.transform import resize
from time import time
from sklearn.decomposition import PCA
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
import glob # for bulk file import
import os


# Set defaults
plt.rcParams['image.cmap'] = 'gray' # Display grayscale images in... grayscale.
plt.rcParams['image.interpolation'] = 'none' # Use nearest-neighbour
plt.rcParams['figure.figsize'] = 10, 10

# Import test images
#imgpaths = glob.glob("./images/*.jpg") + glob.glob("./images/*.png")

os.getcwd()
os.chdir("/home/guido/NEU")

##loading trash images path
imgpathsTrash = glob.glob("./GitHub/Image_Analysis_in_Python/images/trash/*.JPEG")
imgpathsTrash = glob.glob("./DA 5030 Introduction to Data MiningMachine Learning/FinalProject/311pictures/Trash/*.jpg")
imgpathsTrash = imgpathsTrash[0:300] 

##loading trash images path
imgpathsCar = glob.glob("./GitHub/Image_Analysis_in_Python/images/car/*.JPEG")
imgpathsCar = imgpathsCar[0:400]

##loading grafiti images path
imgpathsGrafiti = glob.glob("./DA 5030 Introduction to Data MiningMachine Learning/FinalProject/311pictures/Grafiti/*.jpg")
imgpathsGrafiti = imgpathsGrafiti[0:300]

##loading other images path
imgpathsOther = glob.glob("./DA 5030 Introduction to Data MiningMachine Learning/FinalProject/311pictures/Other/*.jpg")
imgpathsOther = imgpathsOther[0:300]


imgpaths = imgpathsTrash + imgpathsGrafiti + imgpathsOther

y1 = np.zeros(len(imgpathsTrash))
y2 = np.zeros(len(imgpathsGrafiti)) + 1
y3 = np.zeros(len(imgpathsOther)) + 2

y= np.concatenate((y1,y2, y3), axis=0)
y.shape

# imgpaths = glob.glob("images/*.jpg") + glob.glob("images/*.png")  Windows
# Windows has different relative paths than Mac/Unix
#imgset = [mpimg.imread(x) for x in imgpaths]
    
    

# Find horizontal edges using a simple shifting method
def find_horizontal_edges(img):
    imgbw = img_as_float(color.rgb2grey(img))
    return np.abs(imgbw[:, 1:] - imgbw[:, :-1])

# Find vertical edges using a simple shifting method
def find_vertical_edges(img):
    imgbw = img_as_float(color.rgb2grey(img))
    return np.abs(imgbw[1:, :] - imgbw[:-1, :])

# Downsample an image by skipping indicies
def downsample_image(img, skip):
     return img[::skip,::skip]





plt.imshow(image)
plt.imshow(img)
plt.imshow(img_ds)

#only for test
#imgpaths = imgpaths[1:1500]

##extract the number of features
img = mpimg.imread(imgpaths[1])
img = downsample_image(img, 3)
img = find_vertical_edges(img)
img = resize(img, (400, 400))
img_vec =  img.reshape((1, -1))
n_features = img_vec.shape[1]

#create the master vector
X = np.zeros((len(imgpaths), n_features))
w,h = (400,400)
#Redifininf the opening of the images
for i,x in enumerate(imgpaths):
    #read the image in a vector
    img = mpimg.imread(x)
    #downsampling the image
    img = downsample_image(img, 3)
    #finding edge
    img = find_vertical_edges(img)
    #resize the image
    img = resize(img, (400, 400))
    #flatend the image to a vector
    img_vec =  img.reshape((1, -1)) 
    if (img_vec.shape[1] != n_features):
        print('image not procesed: %s' %x)
    else:
        #store the image 
        X[i] = img_vec

###############################################################################
# Split into a training set and a test set using a stratified k fold

# split into a training and testing set
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42)

X=0

###############################################################################
# Compute a PCA (eigenfaces) on the face dataset (treated as unlabeled
# dataset): unsupervised feature extraction / dimensionality reduction
n_components = 150

print("Extracting the top %d eigenfaces from %d faces"
      % (n_components, X_train.shape[0]))
t0 = time()
pca = PCA(n_components=n_components, svd_solver='randomized',
          whiten=True).fit(X_train)
print("done in %0.3fs" % (time() - t0))

eigenfaces = pca.components_.reshape((n_components, h, w))

print("Projecting the input data on the eigenfaces orthonormal basis")
t0 = time()
X_train_pca = pca.transform(X_train)
X_test_pca = pca.transform(X_test)
print("done in %0.3fs" % (time() - t0))

###############################################################################
# Train a SVM classification model

print("Fitting the classifier to the training set")
t0 = time()
param_grid = {'C': [1e3, 5e3, 1e4, 5e4, 1e5],
              'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1], }
clf = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)
clf = clf.fit(X_train_pca, y_train)
print("done in %0.3fs" % (time() - t0))
print("Best estimator found by grid search:")
print(clf.best_estimator_)


###############################################################################
# Quantitative evaluation of the model quality on the test set
n_classes = 3
target_names = ['trash','grafiti', 'other']
print("Predicting people's names on the test set")
t0 = time()
y_pred = clf.predict(X_test_pca)
print("done in %0.3fs" % (time() - t0))
print(classification_report(y_test, y_pred, target_names=target_names))
print(confusion_matrix(y_test, y_pred, labels=range(n_classes)))


# Apply to image set
for i,img in enumerate(imgset):
    plt.figure()
    plt.subplot(1, 3, 1)
    plt.title('Original')
    plt.imshow(img)
    plt.subplot(1, 3, 2)
    plt.title('Horizontal Edges')
    plt.imshow(find_horizontal_edges(img))
    plt.subplot(1, 3, 3)
    plt.title('Vertical Edges')
    plt.imshow(find_vertical_edges(img))
    
    
    
# Apply to image set
for i,img in enumerate(imgset):
    img = downsample_image(img, 3) # downsample    
    plt.figure()
    plt.subplot(1, 3, 1)
    plt.title('Original')
    plt.imshow(img)
    plt.subplot(1, 3, 2)
    plt.title('Horizontal Edges')
    plt.imshow(find_horizontal_edges(img))
    plt.subplot(1, 3, 3)
    plt.title('Vertical Edges')
    plt.imshow(find_vertical_edges(img))

for i,img in enumerate(imgset):
    print i
    print img
    print len(find_vertical_edges(img))































    