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

Upload New File

parent 5811f3ed
Branches
Tags
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