Segmentation de lignes épaisses superposées sur une image binaire
J'ai une image binaire comme indiqué ci-dessous après avoir appliqué divers pipelines de prétraitement et de détection sur l'image d'origine.

Comme on le voit sur la photo, il y a en fait 2 pistes (tarmacs) pour les avions qui se croisent sur une zone d'intersection. Ce dont j'ai besoin, c'est de diviser les deux pistes et de rendre leurs contours. J'ai vérifié les fonctions d'opencv concernant les caractéristiques de contour mais je n'ai pas eu de chance. cv2.fitLine
semble correct mais cela ne fonctionne que s'il n'y a qu'une seule ligne dans le contour. L'image résultante lorsque les masques sont appliqués doit ressembler à ceci:

Réponses
Voici une approche possible, juste faite dans Terminal avec ImageMagick , mais vous devriez pouvoir faire à peu près la même chose en Python avec Wand ou avec scikit-image et medial_axis .
Tout d'abord, squelettisez l'image:
magick runways.png -threshold 50% -morphology Thinning:-1 Skeleton skeleton.png

Ensuite, lancez une "Détection de ligne Hough" à la recherche de lignes de plus de 130 pixels et demandez les résultats sous forme de tableau:
magick skeleton.png -hough-lines 9x9+130 mvg:-
Production
# Hough line transform: 9x9+130
viewbox 0 0 464 589
# x1,y1 x2,y2 # count angle distance
line 297.15,0 286.869,589 # 255 1 476
line 0,591.173 464,333.973 # 189 61 563
Cela signifie qu'il a détecté 2 lignes:
- une ligne allant des coordonnées 297,0 aux coordonnées 286 589, avec une longueur = 255 pixels à 1 degré par rapport à la verticale
- une ligne allant des coordonnées 0,591 aux coordonnées 464333, d'une longueur = 189 pixels à 61 degrés par rapport à la verticale
Juste pour illustrer, je vais dessiner le premier en rouge et le second en vert:
magick runways.png \
-fill red -draw "line 297,0 286,589" \
-fill lime -draw "line 0,591 464,333" result.png

Mots clés : Python, traitement d'image, squelette, squelette, éclaircie, piste, pistes, intersection, détection de ligne Hough.
J'ai essayé de résoudre votre problème avec C ++ en référençant mon ancienne réponse .
quelques étapes:
--after finding contours find defect points by convexityDefects
approxPolyDP(contours[i], contours[i], 9, true);
convexHull(contours[i], contoursHull, true);
convexityDefects(contours[i], contoursHull, defects);

créer deux copies d'une image binaire et dessiner des lignes en utilisant des points de défaut
Vec4i defpoint0 = defects[0];
Vec4i defpoint1 = defects[1];
Vec4i defpoint2 = defects[2];
Vec4i defpoint3 = defects[3];
line(bw0, contours[i][defpoint0[2]], contours[i][defpoint1[2]], Scalar(0), 2);
line(bw0, contours[i][defpoint2[2]], contours[i][defpoint3[2]], Scalar(0), 2);
line(bw1, contours[i][defpoint0[2]], contours[i][defpoint3[2]], Scalar(0), 2);
line(bw1, contours[i][defpoint1[2]], contours[i][defpoint2[2]], Scalar(0), 2);


trouver des contours à partir d'images et les dessiner (i index de contour trouvé codé en dur, doit être amélioré)
findContours(bw0, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
drawContours(src, contours, 1, Scalar((rand() & 255), (rand() & 255), (rand() & 255)), 2);
findContours(bw1, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
drawContours(src, contours, 2, Scalar((rand() & 255), (rand() & 255), (rand() & 255)), 2);

#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat src = imread("e:/test/crossing_lines.png");
if (src.empty())
return -1;
Mat bw,bw0,bw1;
cvtColor(src, bw, COLOR_BGR2GRAY);
bw = bw > 127;
bw0 = bw.clone();
bw1 = bw.clone();
// Find contours
vector<vector<Point> > contours;
vector<int> contoursHull;
vector<Vec4i> defects;
findContours(bw, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
for (size_t i = 0; i < contours.size(); i++)
{
if (contourArea(contours[i]) > 500)
{
approxPolyDP(contours[i], contours[i], 9, true);
convexHull(contours[i], contoursHull, true);
convexityDefects(contours[i], contoursHull, defects);
Vec4i defpoint0 = defects[0];
Vec4i defpoint1 = defects[1];
Vec4i defpoint2 = defects[2];
Vec4i defpoint3 = defects[3];
line(bw0, contours[i][defpoint0[2]], contours[i][defpoint1[2]], Scalar(0), 2);
line(bw0, contours[i][defpoint2[2]], contours[i][defpoint3[2]], Scalar(0), 2);
line(bw1, contours[i][defpoint0[2]], contours[i][defpoint3[2]], Scalar(0), 2);
line(bw1, contours[i][defpoint1[2]], contours[i][defpoint2[2]], Scalar(0), 2);
}
}
findContours(bw0, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
drawContours(src, contours, 1, Scalar((rand() & 255), (rand() & 255), (rand() & 255)), 2);
findContours(bw1, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
drawContours(src, contours, 2, Scalar((rand() & 255), (rand() & 255), (rand() & 255)), 2);
imshow("src", src);
imshow("bw0", bw0);
imshow("bw1", bw1);
waitKey();
return 0;
}