Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
T
TB2023Max
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
maxamed.nuurmaxa
TB2023Max
Commits
807a9c2c
Commit
807a9c2c
authored
1 year ago
by
maxamed.nuurmaxa
Browse files
Options
Downloads
Patches
Plain Diff
Upload New File
parent
5811f3ed
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
Méthode traditionnelle/mes_fonctions.py
+396
-0
396 additions, 0 deletions
Méthode traditionnelle/mes_fonctions.py
with
396 additions
and
0 deletions
Méthode traditionnelle/mes_fonctions.py
0 → 100644
+
396
−
0
View file @
807a9c2c
# -*- 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
#%%
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment