faceshape = (80,80)
ws = []
hs = []
data = []

for (path, label) in labelled_paths:
    im = cv2.imread(path, 0)
    faces = face_cascade.detectMultiScale(im, 1.3, 5)
    if faces == ():
        #print 'missed a face'
        continue
    else:
        (x,y,w,h) = faces.tolist()[0]
        cropped = im[y:y+h, x:x+w]
        reshaped = cv2.resize(cropped, faceshape, interpolation=cv2.INTER_LINEAR)
        data.append(reshaped.flatten())
        #labels.append(label)
        #ws.append(w)
        #hs.append(h)
        
#(np.mean(ws), np.std(ws), np.mean(hs), np.std(hs))
labels0 = np.zeros(len(data))
df0 = pd.DataFrame(data)

# test!
im = Image.fromarray(reshaped)
#im.show()
reshaped.flatten()

"""
Explanation: I've run face cropping, then calculated averages and standard deviations of widths/heights. Outcomes: cascades detect square "faces", the average size is 78.6px with standard deviation of 6px. Based on this I will resize all cropped images to 80px sized square for analysis.
End of explanation
"""


data = []
for path in glob('gedfaces/*'):
    imc = cv2.imread(path, 1)
    im = cv2.cvtColor(imc, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(im, 1.3, 5)
    if faces == ():
        print 'missed a face'
        continue
    else:
        (x,y,w,h) = faces.tolist()[0]
        cropped = im[y:y+h, x:x+w]
        reshaped = cv2.resize(cropped, faceshape, interpolation=cv2.INTER_LINEAR)
        data.append(reshaped.flatten())
        #labels.append(label)

labels1 = np.ones(len(data))
df1 = pd.DataFrame(data)

data = []
for path in glob('other_faces/*'):
    imc = cv2.imread(path, 1)
    im = cv2.cvtColor(imc, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(im, 1.3, 5)
    if faces == ():
        print 'missed a face'
        continue
    else:
        (x,y,w,h) = faces.tolist()[0]
        cropped = im[y:y+h, x:x+w]
        reshaped = cv2.resize(cropped, faceshape, interpolation=cv2.INTER_LINEAR)
        data.append(reshaped.flatten())
        #labels.append(label)

labels2 = np.zeros(len(data))
df2 = pd.DataFrame(data)

"""
Explanation: Now load my face into the thingie!
End of explanation
"""


labels = np.concatenate((labels0, labels1, labels2))
df = df0.append(df1).append(df2)

"""
Explanation: Join the data.
End of explanation
"""


from sklearn.grid_search import GridSearchCV
from sklearn.learning_curve import learning_curve, validation_curve

from sklearn.linear_model import LogisticRegression
model = LogisticRegression()

# shuffle data!
indices = np.random.permutation(labels.shape[0])
labels_sh, df_sh = labels[indices], df.iloc[indices]
df_sh = df_sh.reset_index(drop=True)

%%time
c_range = np.logspace(-3, 3, 13)
train_scores, valid_scores = validation_curve(model, df_sh, labels_sh, "C", c_range, scoring='f1', cv=3, n_jobs=4)
vd = pd.DataFrame({'sc_train': train_scores.mean(1), 'sc_val': valid_scores.mean(1)}, index=c_range)
vd.plot(kind='line')

%%time
n_train, train_scores, valid_scores = learning_curve(model, df_sh, labels_sh, train_sizes=np.linspace(0.3,1,10), scoring='f1', cv=3, n_jobs=4)
ld = pd.DataFrame({'sc_train': train_scores.mean(1), 'sc_val': valid_scores.mean(1)}, index=n_train)
ld.plot(kind='line')

"""
Explanation: Training logistic regression
End of explanation
"""


model.fit(df_sh, labels_sh)

import pickle
pickle.dump(model, open( "model_lgrg.p", "wb" ))

"""
Explanation: Fit and save final model
End of explanation
"""


