Skip to content
Snippets Groups Projects
Commit 807a9c2c authored by maxamed.nuurmaxa's avatar maxamed.nuurmaxa
Browse files

Upload New File

parent 5811f3ed
No related branches found
No related tags found
No related merge requests found
# -*- coding: utf-8 -*-
"""
Created on Thu May 25 14:03:53 2023
@author: maxamed.nuurmaxa
"""
from skimage.metrics import structural_similarity as compare_ssim
import argparse
import imutils
import cv2
import matplotlib.pyplot as plt
import os
import numpy as np
#%% Récupérer le chemin des images
def get_chemin_images():
# Récupérer le chemin absolu complet vers le dossier contenant le fichier Python en cours d'exécution
script_dir = os.path.dirname(os.path.abspath(__file__))
# Obtenez le chemin complet du dossier "Images"
chemins_dossier_image = os.path.join(script_dir, "T3") # T1 # T2 # T3
# Vérifiez si le chemin correspond à un dossier
if os.path.isdir(chemins_dossier_image):
# Obtenir la liste des éléments dans le dossier "Images"
elements_dossier_image = os.listdir(chemins_dossier_image)
# Parcourir les éléments
liste_chemin_images = []
for element in elements_dossier_image:
chemin_element = os.path.join(chemins_dossier_image, element)
print("Nom de l'élément :", element)
print("Chemin de l'élément :", chemin_element)
print()
liste_chemin_images.append(chemin_element)
return liste_chemin_images
else:
print("Le chemin spécifié ne correspond pas à un dossier.")
#%% Lire les images
def redimensionner_images(imageA, imageB):
# Récupérer les dimensions de l'imageA
hauteurA, largeurA, _ = imageA.shape # dernière valeur canal de couleur
# Redimensionner l'imageB pour qu'elle ait les mêmes dimensions que l'imageA
imageB = cv2.resize(imageB, (largeurA, hauteurA))
# Convertir les images en niveaux de gris
grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)
# Redimensionner les images en niveaux de gris pour qu'elles aient les mêmes dimensions
grayB = cv2.resize(grayB, (largeurA, hauteurA))
return imageA, imageB, grayA, grayB
#%% Afficher les images
def afficher_image(image):
# Création d'une figure et d'un seul sous-graphique
fig, ax = plt.subplots(1, 1)
# Affichage de l'image
ax.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
ax.set_title("Resultat")
# Suppression des axes
ax.axis('off')
# Affichage de la figure
plt.show()
def afficher_images(imageA, imageB):
# Affichage des images sur un même graphique
fig, axes = plt.subplots(1, 2)
# Affichage de l'image A
axes[0].imshow(cv2.cvtColor(imageA, cv2.COLOR_BGR2RGB))
axes[0].set_title("Image Référence")
axes[0].axis('off')
# Affichage de l'image B
axes[1].imshow(cv2.cvtColor(imageB, cv2.COLOR_BGR2RGB))
axes[1].set_title("Image Erreur")
axes[1].axis('off')
# Ajustement des espacements entre les sous-graphiques
plt.tight_layout()
# Affichage du graphique
# plt.axis("off")
plt.show()
def afficher_histogramme(image_gris):
nbBins = 256
rangePV = [0, 255] # Valeurs possibles des pixels
plt.figure(figsize=(9, 9))
plt.title("Histogramme de l'image en niveaux de gris")
plt.xlabel("Bins")
plt.ylabel("# de Pixels")
plt.hist(image_gris.ravel(), nbBins, rangePV)
plt.grid()
plt.show()
def superposer_images(imageA, imageB, alpha=0.3):
# Convertir les images en format RGBA avec un canal alpha
imageA = cv2.cvtColor(imageA, cv2.COLOR_BGR2RGBA)
imageB = cv2.cvtColor(imageB, cv2.COLOR_BGR2RGBA)
# Créer une copie de l'image B avec une opacité réduite
imageB_transparent = imageB.copy()
imageB_transparent[:, :, 3] = int(alpha * 255)
# Superposer les images
image_superposee = cv2.addWeighted(imageA, 1 - alpha, imageB_transparent, alpha, 0)
# Afficher l'image superposée
plt.imshow(image_superposee)
plt.axis('off')
plt.show()
#%% Application de filtres
def filtrer_et_seuiller(image):
# Appliquer le filtre médian avec une taille de noyau de 9x9
filtre_median = cv2.medianBlur(image, 9)
# Appliquer le flou gaussien avec une taille de noyau de 15x15
gaussian = cv2.GaussianBlur(filtre_median, (15, 15), 0)
# Définir les valeurs de seuil inférieure et supérieure
seuil_inf = 70
seuil_sup = 90
# Appliquer un seuillage binaire inversé pour obtenir une image où seuls les pixels entre les seuils sont conservés
_, threshold = cv2.threshold(gaussian, seuil_inf, 255, cv2.THRESH_BINARY_INV)
# Les pixels en dehors de l'intervalle de seuil sont définis à 0 (noir)
threshold[threshold != 255] = 0
return threshold
#%% Contour et rogner
def trouver_et_rogner_contour(image, imageA):
# Appliquer une opération de morphologie pour améliorer les contours
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
closed = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)
# Trouver les contours dans l'image fermée
contours, _ = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Tri des contours par aire (surface)
contours = sorted(contours, key=cv2.contourArea, reverse=True)
# Sélectionner le plus grand contour
top_contour = contours[:1]
# Dessiner le plus grand contour sur une nouvelle image
top_contour_image = np.zeros_like(imageA)
image_contour = cv2.drawContours(top_contour_image, top_contour, -1, (0, 255, 0), 5)
# Obtenir les coordonnées du contour
x, y, w, h = cv2.boundingRect(top_contour[0])
# Extraire la région d'intérêt (ROI) de l'image en utilisant les coordonnées du contour
cropped_image = imageA[y:y+h, x:x+w]
return image_contour, cropped_image, x, y, w, h, top_contour, top_contour_image
#%% Essaies 1 meilleure correspondance
# def feature_extraction(image):
# # Créer un détecteur de points d'intérêt ORB
# orb = cv2.ORB_create()
# # Trouver les points d'intérêt et les descripteurs dans l'image
# keypoints, descriptors = orb.detectAndCompute(image, None)
# return keypoints, descriptors
# def feature_matching(descriptors_A, descriptors_B):
# # Créer un matcher descripteur par force brute (brute force)
# bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# # Effectuer une correspondance des descripteurs entre les deux images
# matches = bf.match(descriptors_A, descriptors_B)
# # Trier les correspondances par distance croissante
# matches = sorted(matches, key=lambda x: x.distance)
# return matches
# imageA = cropped_image_A
# imageB = cropped_image_B
# # Extraire les points caractéristiques et les descripteurs des deux images
# keypoints_A, descriptors_A = feature_extraction(cropped_image_A_1)
# keypoints_B, descriptors_B = feature_extraction(cropped_image_B_1)
# # Effectuer une correspondance des descripteurs
# matches = feature_matching(descriptors_A, descriptors_B)
# # Extraire les coordonnées des points correspondants
# points_A = np.float32([keypoints_A[m.queryIdx].pt for m in matches]).reshape(-1, 1, 2)
# points_B = np.float32([keypoints_B[m.trainIdx].pt for m in matches]).reshape(-1, 1, 2)
# ransacReprojThreshold = 12
# # Estimer la transformation géométrique en utilisant RANSAC
# transformation_matrix, mask = cv2.findHomography(points_B, points_A, cv2.RANSAC, ransacReprojThreshold)
# # Appliquer la transformation à l'image B pour l'aligner sur l'image A
# aligned_image_B = cv2.warpPerspective(cropped_image_B_1, transformation_matrix, (cropped_image_A_1.shape[1], cropped_image_A_1.shape[0]))
# # Calculer le décalage entre les deux images
# decalage_x = transformation_matrix[0, 2]
# decalage_y = transformation_matrix[1, 2]
# # Appliquer la translation à l'image B pour aligner sa position sur l'image A
# translation_matrix = np.float32([[1, 0, decalage_x], [0, 1, decalage_y]])
# translated_image_B = cv2.warpAffine(cropped_image_B_1, translation_matrix, (cropped_image_A_1.shape[1], cropped_image_A_1.shape[0]))
#%% Essai 2 meilleures correspondance
def feature_matching(descriptors_A, descriptors_B):
# Créer un matcher descripteur par force brute (brute force)
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# Effectuer une correspondance des descripteurs entre les deux images
matches = bf.match(descriptors_A, descriptors_B)
# Trier les correspondances par distance croissante
matches = sorted(matches, key=lambda x: x.distance)
return matches
def apply_affine_transform(image, transformation_matrix):
rows, cols = image.shape[:2]
print(rows, cols)
transformed_image = cv2.warpAffine(image, transformation_matrix, (cols, rows))
return transformed_image
def find_best_correspondence(imageA, imageB):
if len(imageA.shape) == 3 and imageA.shape[2] == 3:
# L'image A est en couleur, convertir en niveaux de gris
grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
else:
# L'image A est déjà en niveaux de gris
grayA = imageA
if len(imageB.shape) == 3 and imageB.shape[2] == 3:
# L'image B est en couleur, convertir en niveaux de gris
grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)
else:
# L'image B est déjà en niveaux de gris
grayB = imageB
# Extraire les points caractéristiques et les descripteurs des deux images
orb = cv2.ORB_create()
keypoints_A, descriptors_A = orb.detectAndCompute(grayA, None)
keypoints_B, descriptors_B = orb.detectAndCompute(grayB, None)
# Effectuer une correspondance des descripteurs
matches = feature_matching(descriptors_A, descriptors_B)
# Extraire les coordonnées des points correspondants
points_A = np.float32([keypoints_A[m.queryIdx].pt for m in matches]).reshape(-1, 1, 2)
points_B = np.float32([keypoints_B[m.trainIdx].pt for m in matches]).reshape(-1, 1, 2)
# Estimer une transformation affine en utilisant RANSAC
transformation_matrix, _ = cv2.estimateAffine2D(points_B, points_A, method=cv2.RANSAC)
# Appliquer la transformation affine à l'image B
transformed_imageB = apply_affine_transform(imageB, transformation_matrix)
return transformed_imageB
#%% Difference entre les deux images
def process_images(imageA, imageB):
if len(imageA.shape) == 3 and imageA.shape[2] == 3:
# L'image A est en couleur, convertir en niveaux de gris
gray_cropped_imageA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)
else:
# L'image A est déjà en niveaux de gris
gray_cropped_imageA = imageA
if len(imageB.shape) == 3 and imageB.shape[2] == 3:
# L'image B est en couleur, convertir en niveaux de gris
gray_cropped_imageB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)
else:
# L'image B est déjà en niveaux de gris
gray_cropped_imageB = imageB
# Créer une matrice de taille (taille_noyau_median, taille_noyau_median) pour le filtre médian
taille_noyau_median = 11
Filtre_median_grayA = cv2.medianBlur(gray_cropped_imageA, taille_noyau_median)
Filtre_median_grayB = cv2.medianBlur(gray_cropped_imageB, taille_noyau_median)
# Afficher les images après le filtre médian
afficher_images(Filtre_median_grayA, Filtre_median_grayB)
kernel_size_gaussien = (71, 71)
gaussian_grayA = cv2.GaussianBlur(Filtre_median_grayA, kernel_size_gaussien, 0)
gaussian_grayB = cv2.GaussianBlur(Filtre_median_grayB, kernel_size_gaussien, 0)
# Afficher les images après le filtre gaussien
afficher_images(gaussian_grayA, gaussian_grayB)
# Calcul du score SSIM et de la différence entre les images
(score, diff) = compare_ssim(gaussian_grayA, gaussian_grayB, full=True)
# Mise à l'échelle de la différence entre 0 et 255 pour pouvoir l'afficher
diff = (diff * 255).astype("uint8")
# Affichage du score SSIM
print("SSIM: {}".format(score))
return diff
#%% Traitement
def seuillage_diff_image(diff, best_correspondence_A, best_correspondence_B, pourcentage_marge=5, nombre_objet=3, seuil_taille=0.03):
# Seuillage de la carte de différence en une image binaire
thresh = cv2.threshold(diff, 200, 255, cv2.THRESH_BINARY_INV)[1]
# Recherche des contours dans l'image seuillée
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
# Tri des contours par aire (surface)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
# Créer une image vierge de la même taille que diff
contour_image = np.zeros_like(diff)
# Obtenir les dimensions de l'image
height, width = best_correspondence_A.shape[:2]
# Calcul de la marge pour exclure les contours proches des bords
marge = int(min(height, width) * (pourcentage_marge / 100))
# Créer une nouvelle liste pour stocker les contours valides
cnts_valides = []
# Parcourir tous les contours
for contour in cnts:
# Obtenir le rectangle englobant du contour
x, y, w, h = cv2.boundingRect(contour)
# Vérifier si le contour touche les bords de l'image
if x > marge and y > marge and x + w < width - marge and y + h < height - marge:
# Ajouter le contour à la liste des contours valides
cnts_valides.append(contour)
# Trier les contours valides par aire (en ordre décroissant)
cnts_valides = sorted(cnts_valides, key=cv2.contourArea, reverse=True)
# Rogner les objets inférieurs à un air de 3%
hauteur, largeur, _ = best_correspondence_B.shape
cnts_valides_rogner = cnts_valides[:nombre_objet]
aire_totale = hauteur * largeur
seuil_taille = seuil_taille * aire_totale # Seuil de taille à 3% de l'aire totale
cnts_valides_filtres = []
for contour in cnts_valides_rogner:
aire_contour = cv2.contourArea(contour)
if aire_contour > seuil_taille:
cnts_valides_filtres.append(contour)
# Dessiner les rectangles autour des objets filtrés
for c in cnts_valides_filtres:
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(best_correspondence_B, (x, y), (x + w, y + h), (0, 0, 255), 2)
return best_correspondence_B
#%%
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment