Commit 4c1a1853 authored by robinechuca's avatar robinechuca
Browse files

commit intermediaire

parent 92b2c905
#!/usr/bin/env python3
"""
|===========================================|
| Extrait des caracteristiques d'une image. |
|===========================================|
Ce programme caracterise plus particulierement:
-Luminance moyenne.
-Histogrames:
-HOG
-Luminance
-LBP
"""
import cv2
import glob
import numpy as np
class Critere:
"""
|==========================|
| Extraction des criteres. |
|==========================|
"""
def __init__(self, image):
"""
:param image: L'image sur laquelle on calcule les caracteristiques.
:type image: np.ndarray
"""
assert isinstance(image, np.ndarray), \
"'image' doit etre une array numpy, pas un %." % type(image).__name__
assert image.ndim == 3, "L'image doit etre une image en couleur."
self.image = image
def get_mean(self):
"""
:return: La moyenne de la luminance.
:rtype: float
"""
return np.mean(cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY))
def get_mean_color(self):
"""
:return: La moyenne sur chaque couleur.
:rtype: np.ndarray
"""
return cv2.cvtColor(self.image, cv2.COLOR_BGR2HSV).mean(axis=0).mean(axis=0)
def get_hog(self):
"""
:return: Le vecteur pour chaque angle allant de 0 a 360, la norme du gradient.
:rtype: np.ndarray
"""
def interpol(theta):
"""
Retourne pour les 2 entiers qui encarde theta,
le rapport de distribution entre les 2.
"""
a = int(theta)
b = (a + 1) % 180
ca = 1 - theta + a
cb = 1 - ca
return a, ca, b, cb
lum_image = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
grads, angles = cv2.cartToPolar(
cv2.Sobel(lum_image, cv2.CV_32F, 1, 0, ksize=1), # grad sur x
cv2.Sobel(lum_image, cv2.CV_32F, 0, 1, ksize=1), # grad sur y
angleInDegrees=True) # amplitude, angle
hist = np.zeros(360)
for grad, angle in zip(grads.ravel(), angles.ravel()):
a, ca, b, cb = interpol(angle)
hist[a] += grad*ca
hist[b] += grad*cb
return hist / lum_image.size
def dist_mean(self, other):
"""
Compare la distance de la moyenne de la luminamce entre soit, et l'autre ctritere donne en parametre.
:param other: L'autre critere.
:type other: Critere
:return: La distance normalisee entre 0 et 1.
:rtype: float
"""
assert isinstance(other, Critere), \
"'other' doit etre une instance de Critere, et non pas un %s." % type(other).__name__
return (self.get_mean() - other.get_mean())**2/(255**2)
def dist_mean_color(self, other):
"""
Compare la distance de la moyenne du hsv entre soit, et l'autre ctritere donne en parametre.
:param other: L'autre critere.
:type other: Critere
:return: La distance normalisee entre 0 et 1.
:rtype: float
"""
assert isinstance(other, Critere), \
"'other' doit etre une instance de Critere, et non pas un %s." % type(other).__name__
return np.sum((self.get_mean_color() - other.get_mean_color())**2)/(3*255**2)
def dist_hog(self, other):
"""
Compare la distance du gradient oriante entre soit, et l'autre ctritere donne en parametre.
:param other: L'autre critere.
:type other: Critere
:return: La distance normalisee entre 0 et 1.
:rtype: float
"""
assert isinstance(other, Critere), \
"'other' doit etre une instance de Critere, et non pas un %s." % type(other).__name__
return np.sum((self.get_hog() - other.get_hog())**2) / (2 * 255**2)
def dist_global(self, other, **coeff):
"""
Calcul une distance globale, prenant tous les criters en compte.
:param other: L'autre critere.
:type other: Critere
:param coeff: Les coeficient de ponderation.
:type coeff: dict
:return: La moyenne ponderee.
:rtype: float
"""
DISTANCES = [self.dist_mean, self.dist_mean_color, self.dist_hog]
NOMS = ["mean", "mean_color", "hog"]
coeff_sum = 0
dist_sum = 0
for methode, clef in zip(DISTANCES, NOMS):
c = coeff.get(clef, 1)
coeff_sum += c
if c:
dist_sum += c*methode(other)
return dist_sum/coeff_sum
def show(self):
"""
Affiche l'image.
"""
import matplotlib.pyplot as plt
plt.imshow(self.image[..., ::-1], vmin=0, vmax=255)
plt.show()
def main():
import time
criters = [
Critere(
cv2.imread(chemin, cv2.IMREAD_COLOR))
for chemin in glob.iglob("../../labsessions/lab1/input/*.jpg")]
ref, others = criters[0], criters[1:]
ref.show()
ti = time.time()
bests = sorted(others, key=lambda other: ref.dist_global(other, hog=0, mean=0))[:5]
print(time.time() - ti)
bests[0].show()
if __name__ == '__main__':
main()
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment