Filtre de Canny terminé;
Ajout des fonctions utiles au filtre de Canny dans 'usefull_func.py' Pas de modification important dans 'sobel.py'
This commit is contained in:
parent
7da1c028ac
commit
4aa559772c
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,3 +2,5 @@
|
|||||||
imageEngine/images/
|
imageEngine/images/
|
||||||
imageEngine/test/
|
imageEngine/test/
|
||||||
imageEngine/__pycache__/
|
imageEngine/__pycache__/
|
||||||
|
imageEngine/filters/__pycache__/
|
||||||
|
imageEngine/test.py
|
@ -1,39 +1,32 @@
|
|||||||
from usefull_func import *
|
from copy import deepcopy
|
||||||
from math import sqrt, atan2
|
from filters.usefull_func import *
|
||||||
|
from math import sqrt, atan2, pi
|
||||||
|
|
||||||
#En_cours...
|
|
||||||
def filtre_canny(img):
|
|
||||||
|
|
||||||
def norme_gradient(pixel1, pixel2):
|
def filtreCanny(img, Th):
|
||||||
color_x = pixel1[0]
|
Tl = Th / 2
|
||||||
color_y = pixel2[0]
|
|
||||||
|
|
||||||
norm = round(sqrt(color_x**2 + color_y**2))
|
filtred_image = filtre_gaussien(img)
|
||||||
norm = min(norm, 255)
|
|
||||||
|
|
||||||
grad = atan2(color_y, color_x)
|
norme_gradient, angle_normale_gradient = calculGradient(filtred_image)
|
||||||
return norm, grad
|
|
||||||
|
|
||||||
def liste_normGrad(im1, im2):
|
non_maxima = dltNoMaxima(norme_gradient, angle_normale_gradient)
|
||||||
liste = []
|
|
||||||
for j in range(len(im1)):
|
|
||||||
ligne = []
|
|
||||||
for i in range(len(im1[0])):
|
|
||||||
normGrad = norme_gradient(im1[j][i], im2[j][i])
|
|
||||||
ligne.append(normGrad)
|
|
||||||
liste.append(ligne)
|
|
||||||
return liste
|
|
||||||
|
|
||||||
if not is_greyscale(img):
|
contours = seuillageHysteresis(non_maxima, angle_normale_gradient, Th, Tl)
|
||||||
img = greyscale(img)
|
|
||||||
|
|
||||||
mat_x = [[-1,0,1]]
|
return contours
|
||||||
mat_y = [[1],[0],[-1]]
|
|
||||||
|
|
||||||
#lissage/suppression des bri
|
"""
|
||||||
img_no_bruit = convolution_gauss(img)
|
def filtreCannySemiAuto(img, centile):
|
||||||
Jx = convolution(img, mat_x)
|
filtred_image = filtre_gaussien(img)
|
||||||
Jy = convolution(img, mat_y)
|
|
||||||
normGrad = liste_normGrad(Jx, Jy)
|
|
||||||
#Suppresion des non-maximum
|
|
||||||
|
|
||||||
|
norme_gradient, angle_normale_gradient = calculGradient(filtred_image)
|
||||||
|
|
||||||
|
non_maxima = dltNoMaxima(norme_gradient, angle_normale_gradient)
|
||||||
|
|
||||||
|
Th = calculTh(norme_gradient, centile)
|
||||||
|
Tl = Th / 2
|
||||||
|
contours = seuillageHysteresis(non_maxima, angle_normale_gradient, Th, Tl)
|
||||||
|
|
||||||
|
return contours
|
||||||
|
"""
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
from usefull_func import *
|
from filters.usefull_func import *
|
||||||
|
|
||||||
|
|
||||||
def filtre_sobel(img):
|
def filtre_sobel(img):
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from math import sqrt
|
from copy import deepcopy
|
||||||
|
from math import atan2, sqrt, pi
|
||||||
|
|
||||||
def greyscale(mat_img):
|
def greyscale(mat_img):
|
||||||
gray_img = []
|
gray_img = []
|
||||||
@ -10,26 +11,29 @@ def greyscale(mat_img):
|
|||||||
gray_img.append(lig)
|
gray_img.append(lig)
|
||||||
return gray_img
|
return gray_img
|
||||||
|
|
||||||
|
|
||||||
def appliquer_convolution(img, mat, i, j):
|
def appliquer_convolution(img, mat, i, j):
|
||||||
somme = 0
|
somme = 0
|
||||||
for y in range(len(mat)):
|
for x in range(len(mat)):
|
||||||
for x in range(len(mat[0])):
|
for y in range(len(mat[0])):
|
||||||
pixel_i = i - (len(mat[0]) // 2) + x
|
coord_i = i - (len(mat) // 2) + x
|
||||||
pixel_j = j - (len(mat) // 2) + y
|
corrd_j = j - (len(mat[0]) // 2) + y
|
||||||
pix = pixel(img, pixel_i, pixel_j)
|
pix = pixel(img, coord_i, corrd_j)
|
||||||
somme += pix[0]*mat[y][x]
|
somme += pix[0]*mat[x][y]
|
||||||
return min(max(somme,0), 255)
|
return min(max(somme,0), 255)
|
||||||
|
|
||||||
|
|
||||||
def convolution(mat_img, mat):
|
def convolution(mat_img, mat):
|
||||||
return_img = []
|
return_img = []
|
||||||
for j in range(len(mat_img)):
|
for i in range(len(mat_img)):
|
||||||
ligne = []
|
ligne = []
|
||||||
for i in range(len(mat_img[0])):
|
for j in range(len(mat_img[0])):
|
||||||
val = appliquer_convolution(mat_img, mat, i, j)
|
val = appliquer_convolution(mat_img, mat, i, j)
|
||||||
ligne.append((val,)*3)
|
ligne.append((val,)*3)
|
||||||
return_img.append(ligne)
|
return_img.append(ligne)
|
||||||
return return_img
|
return return_img
|
||||||
|
|
||||||
|
|
||||||
def is_greyscale(img):
|
def is_greyscale(img):
|
||||||
_greyscale = True
|
_greyscale = True
|
||||||
for ligne in img:
|
for ligne in img:
|
||||||
@ -41,6 +45,7 @@ def is_greyscale(img):
|
|||||||
break
|
break
|
||||||
return _greyscale
|
return _greyscale
|
||||||
|
|
||||||
|
|
||||||
def invert(img):
|
def invert(img):
|
||||||
result_image = []
|
result_image = []
|
||||||
for ligne in img:
|
for ligne in img:
|
||||||
@ -50,25 +55,28 @@ def invert(img):
|
|||||||
result_image.append(result_ligne)
|
result_image.append(result_ligne)
|
||||||
return result_image
|
return result_image
|
||||||
|
|
||||||
|
|
||||||
def pixel(img, i, j, default=(0,0,0)):
|
def pixel(img, i, j, default=(0,0,0)):
|
||||||
#i la colone et j la ligne
|
#i la colone et j la ligne
|
||||||
if 0 <= i < len(img[0]) and 0 <= j < len(img):
|
if 0 <= i < len(img) and 0 <= j < len(img[0]):
|
||||||
return img[j][i]
|
return img[i][j]
|
||||||
else:
|
else:
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
||||||
def reduction_bruit(img, mat, i, j):
|
def reduction_bruit(img, mat, i, j):
|
||||||
somme = 0
|
somme = 0
|
||||||
for y in range(len(mat)):
|
for x in range(len(mat)):
|
||||||
for x in range(len(mat[0])):
|
for y in range(len(mat[0])):
|
||||||
pixel_i = i - (len(mat[0]) // 2) + x
|
pixel_i = i - (len(mat) // 2) + x
|
||||||
pixel_j = j - (len(mat) // 2) + y
|
pixel_j = j - (len(mat[0]) // 2) + y
|
||||||
pix = pixel(img, pixel_i, pixel_j)
|
pix = pixel(img, pixel_i, pixel_j)
|
||||||
somme += pix[0]*mat[y][x]
|
somme += pix[0]*mat[x][y]
|
||||||
normalise = round(somme)
|
normalise = round(somme)
|
||||||
return normalise
|
return normalise
|
||||||
|
|
||||||
def convolution_gauss(mat_img):
|
|
||||||
|
def filtre_gaussien(mat_img):
|
||||||
mat_gauss = [
|
mat_gauss = [
|
||||||
[2/159, 4/159, 5/159, 4/159,2/159],
|
[2/159, 4/159, 5/159, 4/159,2/159],
|
||||||
[4/159, 9/159,12/159, 9/159,4/159],
|
[4/159, 9/159,12/159, 9/159,4/159],
|
||||||
@ -78,28 +86,208 @@ def convolution_gauss(mat_img):
|
|||||||
]
|
]
|
||||||
|
|
||||||
return_img = []
|
return_img = []
|
||||||
for j in range(len(mat_img)):
|
for i in range(len(mat_img)):
|
||||||
ligne = []
|
ligne = []
|
||||||
for i in range(len(mat_img[0])):
|
for j in range(len(mat_img[0])):
|
||||||
val = reduction_bruit(mat_img, mat_gauss, i, j)
|
val = reduction_bruit(mat_img, mat_gauss, i, j)
|
||||||
ligne.append((val,)*3)
|
ligne.append((val,)*3)
|
||||||
return_img.append(ligne)
|
return_img.append(ligne)
|
||||||
return return_img
|
return return_img
|
||||||
|
|
||||||
|
|
||||||
def calcul_norme(pixel1, pixel2):
|
def calcul_norme(pixel1, pixel2):
|
||||||
valeur = pixel1[0]**2 + pixel2[0]**2
|
valeur = pixel1[0]**2 + pixel2[0]**2
|
||||||
norm = round(sqrt(valeur))
|
norm = round(sqrt(valeur))
|
||||||
norm = int(min(norm, 255))
|
norm = int(min(norm, 255))
|
||||||
return norm
|
return norm
|
||||||
|
|
||||||
|
|
||||||
def application_norme(im_x, im_y):
|
def application_norme(im_x, im_y):
|
||||||
result_image = []
|
result_image = []
|
||||||
for j in range(len(im_x)):
|
for i in range(len(im_x)):
|
||||||
ligne = []
|
ligne = []
|
||||||
for i in range(len(im_x[0])):
|
for j in range(len(im_x[0])):
|
||||||
pixel1 = im_x[j][i]
|
pixel1 = im_x[i][j]
|
||||||
pixel2 = im_y[j][i]
|
pixel2 = im_y[i][j]
|
||||||
norme = calcul_norme(pixel1, pixel2)
|
norme = calcul_norme(pixel1, pixel2)
|
||||||
ligne.append((norme,)*3)
|
ligne.append((norme,)*3)
|
||||||
result_image.append(ligne)
|
result_image.append(ligne)
|
||||||
return result_image
|
return result_image
|
||||||
|
|
||||||
|
|
||||||
|
def calculGradient(filtred_image):
|
||||||
|
mask_x = [[1, 0, -1]]
|
||||||
|
mask_y = [[1],[0],[-1]]
|
||||||
|
|
||||||
|
mask_gradient_x = convolution(filtred_image, mask_x)
|
||||||
|
mask_gradient_y = convolution(filtred_image, mask_y)
|
||||||
|
|
||||||
|
norme_gradient = copyNullMatrix(filtred_image)
|
||||||
|
angle_normal_gradient = copyNullMatrix(filtred_image)
|
||||||
|
|
||||||
|
for i in range(len(filtred_image)):
|
||||||
|
for j in range(len(filtred_image[0])):
|
||||||
|
Jx = mask_gradient_x[i][j][0]
|
||||||
|
Jy = mask_gradient_y[i][j][0]
|
||||||
|
norme_gradient[i][j] = sqrt(Jx**2 + Jy**2)
|
||||||
|
angle_temp = atan2(Jy,Jx)
|
||||||
|
angle_normal_gradient[i][j] = transform_angle(angle_temp)
|
||||||
|
|
||||||
|
return norme_gradient, angle_normal_gradient
|
||||||
|
|
||||||
|
|
||||||
|
def copyNullMatrix(mat):
|
||||||
|
nullMat = deepcopy(mat)
|
||||||
|
for i in range(len(nullMat)):
|
||||||
|
for j in range(len(nullMat[0])):
|
||||||
|
nullMat[i][j] = 0
|
||||||
|
return nullMat
|
||||||
|
|
||||||
|
|
||||||
|
def transform_angle(radient):
|
||||||
|
angle = radient * 180 / pi
|
||||||
|
if angle < 0:
|
||||||
|
angle += 180
|
||||||
|
|
||||||
|
#On veut que la valeur de l'angle soit 0, 45, 90 ou 135°
|
||||||
|
seuil_min_45 = 45/2
|
||||||
|
seuil_min_90 = (90+45)/2
|
||||||
|
seuil_min_135 = (135+90)/2
|
||||||
|
seuil_max_135 = (180+135)/2
|
||||||
|
|
||||||
|
if seuil_min_45 <= angle < seuil_min_90:
|
||||||
|
angle = 45
|
||||||
|
elif seuil_min_90 <= angle < seuil_min_135:
|
||||||
|
angle = 90
|
||||||
|
elif seuil_min_135 <= angle < seuil_max_135:
|
||||||
|
angle = 135
|
||||||
|
else:
|
||||||
|
angle = 0
|
||||||
|
|
||||||
|
return angle
|
||||||
|
|
||||||
|
|
||||||
|
def dltNoMaxima(norme_gradient, angle_normal_gradient):
|
||||||
|
non_maxima = copyNullMatrix(norme_gradient)
|
||||||
|
|
||||||
|
for i in range(len(non_maxima)):
|
||||||
|
for j in range(len(non_maxima[0])):
|
||||||
|
angle = angle_normal_gradient[i][j]
|
||||||
|
voisin1, voisin2 = norm_voisin(norme_gradient, angle, i, j)
|
||||||
|
if norme_gradient[i][j] < voisin1 or norme_gradient[i][j] < voisin2:
|
||||||
|
non_maxima[i][j] = 0
|
||||||
|
else:
|
||||||
|
non_maxima[i][j] = norme_gradient[i][j]
|
||||||
|
return non_maxima
|
||||||
|
|
||||||
|
|
||||||
|
def get_norm(norm_list, i, j):
|
||||||
|
norm = 0
|
||||||
|
if 0 <= i < len(norm_list) and 0 <= j < len(norm_list[0]):
|
||||||
|
norm = norm_list[i][j]
|
||||||
|
return norm
|
||||||
|
|
||||||
|
|
||||||
|
def norm_voisin(norm_list, angle, i, j):
|
||||||
|
voisin1 = None
|
||||||
|
voisin2 = None
|
||||||
|
|
||||||
|
if angle == 0:
|
||||||
|
voisin1 = get_norm(norm_list,i,j-1)
|
||||||
|
voisin2 = get_norm(norm_list,i,j+1)
|
||||||
|
elif angle == 45:
|
||||||
|
voisin2 = get_norm(norm_list,i-1,j+1)
|
||||||
|
voisin1 = get_norm(norm_list,i+1,j-1)
|
||||||
|
elif angle == 90:
|
||||||
|
voisin1 = get_norm(norm_list,i-1,j)
|
||||||
|
voisin2 = get_norm(norm_list,i+1,j)
|
||||||
|
elif angle == 135:
|
||||||
|
voisin2 = get_norm(norm_list,i-1,j-1)
|
||||||
|
voisin1 = get_norm(norm_list,i+1,j+1)
|
||||||
|
|
||||||
|
return voisin1, voisin2
|
||||||
|
|
||||||
|
|
||||||
|
def seuillageHysteresis(non_maxima, angle_normale_gradient, Th, Tl):
|
||||||
|
contours = deepcopy(non_maxima)
|
||||||
|
|
||||||
|
for i in range(len(angle_normale_gradient)):
|
||||||
|
for j in range(len(angle_normale_gradient[0])):
|
||||||
|
if non_maxima[i][j] > Th:
|
||||||
|
contours[i][j] = (255,)*3
|
||||||
|
elif non_maxima[i][j] < Tl:
|
||||||
|
contours[i][j] = (0,)*3
|
||||||
|
|
||||||
|
|
||||||
|
for i in range(len(angle_normale_gradient)):
|
||||||
|
for j in range(len(angle_normale_gradient[0])):
|
||||||
|
if Tl <= non_maxima[i][j] <= Th:
|
||||||
|
angle = angle_normale_gradient[i][j] + 90
|
||||||
|
if angle >= 180:
|
||||||
|
angle -= 180
|
||||||
|
|
||||||
|
voisin1, voisin2 = norm_voisin(non_maxima, angle, i, j)
|
||||||
|
if voisin1 > Th and voisin2 > Th:
|
||||||
|
contours[i][j] = (255,)*3
|
||||||
|
else:
|
||||||
|
contours[i][j] = (0,)*3
|
||||||
|
return contours
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
def calculTh(norme_gradient, centile):
|
||||||
|
histogramme, pas = calculHistogram(norme_gradient)
|
||||||
|
fonctionRepartition = calculFonctionRepartition(histogramme)
|
||||||
|
|
||||||
|
nbrPixels = len(norme_gradient)*len(norme_gradient[0])
|
||||||
|
pivot = nbrPixels * centile
|
||||||
|
|
||||||
|
Th_index = 0
|
||||||
|
for i in range(len(fonctionRepartition)):
|
||||||
|
if (pivot - fonctionRepartition[0][Th_index]) > (pivot - fonctionRepartition[0][i]) and (pivot - fonctionRepartition[i] > 0):
|
||||||
|
Th_index = i
|
||||||
|
|
||||||
|
Th = pas * (Th_index - 1)
|
||||||
|
return Th
|
||||||
|
|
||||||
|
def calculHistogram(norme_gradient):
|
||||||
|
norme_max = Maxi(norme_gradient)
|
||||||
|
norme_min = Minim(norme_gradient)
|
||||||
|
ecart = norme_max - norme_min
|
||||||
|
|
||||||
|
nb_pas = 1000
|
||||||
|
pas = ecart / (nb_pas - 1)
|
||||||
|
|
||||||
|
histogram = [[0]*nb_pas]
|
||||||
|
|
||||||
|
for i in range(len(norme_gradient)):
|
||||||
|
for j in range(len(norme_gradient[0])):
|
||||||
|
valeur_pixel = norme_gradient[i][j]
|
||||||
|
position = floor((valeur_pixel - norme_min) / pas)
|
||||||
|
histogram[0][position] += 1
|
||||||
|
|
||||||
|
return histogram, pas
|
||||||
|
|
||||||
|
def calculFonctionRepartition(histogram):
|
||||||
|
fonctionRepartition = deepcopy(histogram)
|
||||||
|
for i in range(1, len(fonctionRepartition[0])):
|
||||||
|
fonctionRepartition[0][i] = fonctionRepartition[0][i-1] + histogram[0][i-1]
|
||||||
|
|
||||||
|
return fonctionRepartition
|
||||||
|
|
||||||
|
def Maxi(mat):
|
||||||
|
mx = 0
|
||||||
|
for i in range(len(mat)):
|
||||||
|
for j in range(len(mat[0])):
|
||||||
|
if mat[i][j] > mx:
|
||||||
|
mx = mat[i][j]
|
||||||
|
return mx
|
||||||
|
|
||||||
|
def Minim(mat):
|
||||||
|
mn = 1000
|
||||||
|
for i in range(len(mat)):
|
||||||
|
for j in range(len(mat[0])):
|
||||||
|
if mat[i][j] < mn:
|
||||||
|
mn = mat[i][j]
|
||||||
|
return mn
|
||||||
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user