Segmentazione di linee spesse sovrapposte su un'immagine binaria
Ho un'immagine binaria come mostrato di seguito dopo aver applicato varie pipeline di pre-elaborazione e rilevamento sull'immagine originale.

Come si vede nella foto, ci sono in realtà 2 piste (asfalto) per aerei che si incrociano in una regione di intersezione. Quello di cui ho bisogno è dividere entrambe le piste e restituire i loro contorni. Ho controllato le funzioni di opencv per quanto riguarda le caratteristiche del contorno ma non ho avuto fortuna. cv2.fitLine
sembra ok ma funziona solo se c'è una sola linea nel contorno. L'immagine risultante quando vengono applicate le maschere dovrebbe essere simile a questa:

Risposte
Ecco un possibile approccio, appena fatto in Terminal con ImageMagick , ma dovresti essere in grado di fare più o meno lo stesso in Python con Wand o con scikit-image e medial_axis .
Per prima cosa, scheletrizza l'immagine:
magick runways.png -threshold 50% -morphology Thinning:-1 Skeleton skeleton.png

Quindi esegui un "Hough Line Detection" cercando linee più lunghe di 130 pixel e chiedi i risultati in forma tabulare:
magick skeleton.png -hough-lines 9x9+130 mvg:-
Produzione
# 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
Ciò significa che ha rilevato 2 linee:
- una linea dalle coordinate 297,0 alle coordinate 286,589, con una lunghezza = 255 pixel a 1 grado rispetto alla verticale
- una linea dalle coordinate 0,591 alle coordinate 464,333, con una lunghezza = 189 pixel a 61 gradi rispetto alla verticale
Tanto per illustrare, disegnerò il primo in rosso e il secondo in verde:
magick runways.png \
-fill red -draw "line 297,0 286,589" \
-fill lime -draw "line 0,591 464,333" result.png

Parole chiave : Python, elaborazione delle immagini, scheletro, scheletrato, diradamento, pista, piste, intersezione, rilevamento linea di Hough.
Ho provato a risolvere il tuo problema con C ++ facendo riferimento alla mia vecchia risposta .
alcuni passaggi:
--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);

creare due copie dell'immagine binaria e tracciare linee utilizzando i punti difettosi
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);


trova i contorni dalle immagini e disegnali (ho trovato un indice di contorno codificato, deve essere migliorato)
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;
}