Détection de segments dans une image

Links: notebook, html, PDF, python, slides, GitHub

C’est une technique assez vieille et qui consiste à détecter des segments comme des anomalies : l’alignement de points est un événement assez rare dans un nuage de points mais rare comment ? Cette idée mène à la probabilisation d’une image pour quantifier ce qu’est un alignement de points nécessairement rare.

from jyquickhelper import add_notebook_menu
add_notebook_menu()

Une image aléatoire

On considère un bruit aléatoire uniforme dans une image et on ajoute des points aléatoires tirés le long d’une ligne selon une loi gaussienne : uniforme sur la ligne, gaussien autour du segment.

from mlstatpy.image.detection_segment import random_noise_image, convert_array2PIL
img = random_noise_image((100, 100))
convert_array2PIL(img, mode="binary")
../_images/segment_detection_3_0.png
from mlstatpy.image.detection_segment import random_segment_image
random_segment_image(img, density=3., lmin=0.3)
{'size': 36,
 'angle': 2.285619160431492,
 'x1': 23.597410654261072,
 'y1': 40,
 'x2': 0,
 'y2': 67.18753777770554,
 'nbpoints': 108}
convert_array2PIL(img, mode="binary")
../_images/segment_detection_5_0.png
random_segment_image(img, density=5., lmin=0.3)
random_segment_image(img, density=5., lmin=0.3)
convert_array2PIL(img, mode="binary")
../_images/segment_detection_6_0.png
pilimg = convert_array2PIL(img, mode="binary").convert('RGB')
pilimg
../_images/segment_detection_7_0.png
from PIL import ImageFilter


pilimg = pilimg.filter(ImageFilter.BLUR).filter(ImageFilter.BLUR).filter(ImageFilter.BLUR).filter(ImageFilter.BLUR)
pilimg
../_images/segment_detection_8_0.png
from PIL import ImageEnhance
enh = ImageEnhance.Sharpness(pilimg)
final_img = enh.enhance(4)
final_img
../_images/segment_detection_9_0.png

Gradient

La détection des segments est basée sur le gradient.

from mlstatpy.image.detection_segment import compute_gradient, plot_gradient
grad = compute_gradient(final_img, color=0)
plot_gradient(pilimg.copy(), grad, direction=-2)
../_images/segment_detection_12_0.png

Détection de segments

from mlstatpy.image.detection_segment import detect_segments
seg = detect_segments(final_img, verbose=1, seuil_nfa=1e-1)
len(seg)
n =  1000  ...  82  temps  0.27  sec nalign 298
n =  2000  ...  82  temps  0.52  sec nalign 671
n =  3000  ...  164  temps  0.83  sec nalign 964
n =  4000  ...  164  temps  1.10  sec nalign 1357
n =  5000  ...  249  temps  1.39  sec nalign 1544
n =  6000  ...  252  temps  1.66  sec nalign 1924
n =  7000  ...  374  temps  1.95  sec nalign 2183
n =  8000  ...  375  temps  2.23  sec nalign 2460
n =  9000  ...  379  temps  2.56  sec nalign 2728
379
from mlstatpy.image.detection_segment import plot_segments
plot_segments(final_img.copy(), seg)
../_images/segment_detection_15_0.png

Détection de segments sur une image

from PIL import Image
egl = Image.open("eglise_zoom2.jpg")
egl
../_images/segment_detection_17_0.png

On réduit la taille de l’image.

egl2 = egl.crop((0, 0, egl.size[0]//3, 3*egl.size[1]//4))
egl2
../_images/segment_detection_19_0.png
grad2 = compute_gradient(egl2, color=0)
plot_gradient(egl2.copy(), grad2, direction=-2)
../_images/segment_detection_20_0.png
seg2 = detect_segments(egl2)
len(seg2)
490
from mlstatpy.image.detection_segment import plot_segments
res = plot_segments(egl2.copy(), seg2)
res
../_images/segment_detection_22_0.png

Il faudrait fusionner les segments mais cela a l’air de marcher.