# -*- coding: utf-8 -*-
"""
Created on Tue Dec  8 23:00:33 2015

@author: dconduche
"""

import matplotlib.pyplot as plt
import numpy as np
plt.set_cmap('gray')

print("""----------------------Partie A----------------------""")

# Une simple remarque : un tableau numpy a un type, qui n'est pas facilement
# modifiable a posteriori. Donc écrire :

a = np.array([[1, 0], [0, 0]])

# va créer un tableau d'entier (le type est testable via)

print(a.dtype)

# lorsqu'on tape

a[0, 0] = 0.9

# python va d'abord convertir en entier le 0.9 via un int(0.9) implicite

print(a)

print("""----------------------Partie B----------------------
---------------------1) Masques---------------------""")

a = np.random.rand(20, 20)
a[a > .5] = 1
a[a < .5] = 0
# la probabilité d'avoir une valeur qui vaut exactement .5 en tirant
# un float64 au hasard est quasi nulle.

"""Nous avons augmenté le contraste"""

print("""---------------------2) Tranches---------------------""")

# Remarque : il y a *2* coordonnées dans un tableau

a = np.zeros((20, 20))
# Rayures horizontales (car sur l'ensemble des colonnes: « : »)
#   de la ligne 3 (inclue)
#   à la ligne 15 (exclue)
#   avec un pas de 3 (et une épaisseur de 1, évidemment)
a[3:15:3, :] = 1
plt.imshow(a, interpolation='none')
plt.show()

# Rayures verticales
#   de la ligne 0
#   à la ligne maximale
#   avec un pas de 5
a[:, ::5] = 1
plt.imshow(a, interpolation='none')
plt.show()

# points
a[::4, ::6] = 1
plt.imshow(a, interpolation='none')
plt.show()

# partons d'une image plus vaste, et des blocs
N = 200  # des variables partout. Partout.
a = np.zeros((N, N))
a[10:N-10, 10:N-10] = 1
a[13:N-13, 13:N-13] = 0
plt.imshow(a, interpolation='none')
plt.show()

n = max(N, int(np.sqrt(N-10)*10))  # Pour ne pas sortir du cadre
for j in range(0, n, 4):
    a[j:j+10, j**2//20:j**2//20+3] = 1

#plt.imsave('TrucRate.jpg', a)


print("""----------------------Partie C----------------------
winter is coming""")

a = plt.imread('js.jpg')
plt.imshow(a, interpolation='none')
plt.show()

# taille
print('taille: ', a.shape)

# type, max, min
print('tableau numpy de type entier 8 bit :', a.dtype)
print(a.max)
print(a.min)

print("""----------------------Partie D----------------------
---------------------Exercice 1---------------------""")


def neg_naif(a):
    """en place"""
    n, p = a.shape
    for i in range(n):
        for j in range(p):
            a[i, j] = 256 - a[i, j]


def neg_numpy(a):  # beaucoup plus rapide
    return 256 - a

#neg_naif(a)
#a = neg_numpy(a)

#plt.imshow(a, interpolation='none')
#plt.show()

print("""---------------------Exercice 2---------------------""")


def flou(a, N):
    """Floute une image en niveau de gris
    :a: tableau numpy
    :N: épaisseur du carré de pixel. on prend un carré de coté 2N+1 centré en x
    :return: une image b floutée
    """
    b = a  # on crée un tableau qui contiendra l'image floutée
    n, p = a.shape
    for i in range(N, n-N):
        for j in range(N, p-N):
            b[i, j] = a[i-N:i+N+1, j-N:j+N+1].sum()/(2*N+1)**2
    return b

a = plt.imread('js.jpg')
N = 10
print('flou avec un N de', N)
#a = flou(a, N)
#plt.imshow(a, interpolation='none')
#plt.show()

print("""---------------------Exercice 3---------------------""")


def baisse_r(a, N):
    """baisse la résolution
    :a: tableau numpy
    :N: coté du carré de pixel.
    :return: une image b de résolution //N**2
    """
    n, p = a.shape
    a = a[:(n//N)*N, :(p//N)*N]  # Plus de problème au bord
    b = a[:n//N, :p//N]  # Pour avoir le même dtype que a
    for i in range(n//N):
        for j in range(p//N):
            b[i, j] = a[i*N:(i+1)*N, j*N:(j+1)*N].sum()/N**2
    return b

a = plt.imread('js.jpg')
N = 10
print('flou avec un N de', N)
b = baisse_r(a, N)
plt.imshow(b, interpolation='none')
plt.show()


print("""---------------------Exercice 4---------------------""")
# Pour changer le dtype d'un tableau numpy, google est votre ami:
# change dtype python => premier résultat


def normalise(a):
    """retourne une version normalisée entre -1 et 1 de a
    :a: tableau numpy
    :return: un tableau b de float64 compris entre -1 et 1
    """
    b = a[:, :]  # crée une copie de a
    b = b.astype(np.float64)  # converti le dtype de uint8 vers float64
    b = -1 + 2*(b - b.min())/(b.max()-b.min())
    # Vous pouvez aussi faire des boucles, mais ce sera moins efficace.
    return b
#b = normalise(a)
#print(b.max(), b.min())


def fct_contraste(x, alpha):
    x0 = .75
    if x < 0:
        return -fct_contraste(-x, alpha)
    if 0 <= x < x0:
        return alpha*x/x0
    if x0 <= x <= 1:
        return (1-alpha)*(x-1)/(1-x0) + 1
    return "x doit être compris entre -1 et 1"

vfct_contraste = np.vectorize(fct_contraste)
b = normalise(b)
plt.imshow(b, interpolation='none')
plt.show()
b = vfct_contraste(b, .95)
plt.imshow(b, interpolation='none')
plt.show()
