Segmentando linhas grossas sobrepostas em uma imagem binária
Eu tenho uma imagem binária conforme mostrado abaixo depois de aplicar vários pipelines de pré-processamento e detecção na imagem original.

Como pode ser visto na imagem, existem na verdade 2 pistas (pistas) para aviões que se cruzam em uma região de interseção. O que preciso é dividir as duas pistas e retornar seus contornos. Eu verifiquei as funções do opencv em relação às características de contorno, mas não tive sorte. cv2.fitLine
parece ok, mas só funciona se houver apenas uma linha no contorno. A imagem resultante quando as máscaras são aplicadas deve ter a seguinte aparência:

Respostas
Aqui está uma abordagem possível, feita apenas no Terminal com ImageMagick , mas você deve ser capaz de fazer praticamente o mesmo em Python com Wand ou com scikit-image e o medial_axis .
Primeiro, esqueletize a imagem:
magick runways.png -threshold 50% -morphology Thinning:-1 Skeleton skeleton.png

Em seguida, execute uma "Detecção de linha Hough" procurando linhas com mais de 130 pixels e peça os resultados em uma forma tabular:
magick skeleton.png -hough-lines 9x9+130 mvg:-
Resultado
# 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
Isso significa que detectou 2 linhas:
- uma linha das coordenadas 297,0 às coordenadas 286,589, com um comprimento = 255 pixels a 1 grau na vertical
- uma linha das coordenadas 0,591 às coordenadas 464,333, com um comprimento = 189 pixels a 61 graus na vertical
Só para ilustrar, vou desenhar o primeiro em vermelho e o segundo em verde:
magick runways.png \
-fill red -draw "line 297,0 286,589" \
-fill lime -draw "line 0,591 464,333" result.png

Palavras - chave : Python, processamento de imagem, esqueleto, esqueleto, desbaste, pista, pistas, interseção, Detecção de linha de Hough.
Tentei resolver seu problema com C ++ referenciando minha resposta anterior .
alguns passos:
--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);

crie duas cópias da imagem binária e desenhe linhas usando pontos de defeito
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);


encontre contornos de imagens e desenhe-os (i índice de contorno encontrado codificado, precisa ser melhorado)
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;
}