Menyegmentasikan garis tebal yang tumpang tindih pada gambar biner
Saya memiliki gambar biner seperti yang ditunjukkan di bawah ini setelah menerapkan berbagai jalur praproses dan deteksi ke gambar asli.

Seperti terlihat pada gambar sebenarnya terdapat 2 landasan pacu (aspal) untuk pesawat yang saling bersilangan di suatu wilayah persimpangan. Yang saya butuhkan adalah membagi kedua landasan pacu dan mengembalikan konturnya. Saya telah memeriksa fungsi opencv mengenai fitur kontur tetapi tidak berhasil. cv2.fitLine
tampaknya baik-baik saja tetapi hanya berfungsi jika hanya ada satu garis di kontur. Gambar yang dihasilkan saat masker diterapkan akan terlihat seperti ini:

Jawaban
Berikut adalah pendekatan yang mungkin, baru saja dilakukan di Terminal dengan ImageMagick , tetapi Anda seharusnya dapat melakukan hal yang sama di Python dengan Wand atau dengan scikit-image dan medial_axis .
Pertama, buat kerangka gambar:
magick runways.png -threshold 50% -morphology Thinning:-1 Skeleton skeleton.png

Kemudian jalankan "Deteksi Garis Hough" untuk mencari garis yang lebih panjang dari 130 piksel dan tanyakan hasilnya dalam bentuk tabel:
magick skeleton.png -hough-lines 9x9+130 mvg:-
Keluaran
# 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
Itu berarti telah mendeteksi 2 baris:
- garis dari koordinat 297,0 ke koordinat 286.589, dengan panjang = 255 piksel pada 1 derajat vertikal
- garis dari koordinat 0,591 ke koordinat 464,333, dengan panjang = 189 piksel pada 61 derajat vertikal
Sebagai ilustrasi, saya akan menggambar yang pertama dengan warna merah dan yang kedua dengan warna hijau:
magick runways.png \
-fill red -draw "line 297,0 286,589" \
-fill lime -draw "line 0,591 464,333" result.png

Kata kunci : Python, pengolahan citra, skeleton, skeletonise, penipisan, runway, runway, intersection, Hough Line Detection.
Saya mencoba memecahkan masalah Anda dengan C ++ dengan merujuk jawaban lama saya .
beberapa langkah:
--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);

buat dua salinan gambar biner dan gambar garis menggunakan titik cacat
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);


temukan kontur dari gambar dan gambarkan (i indeks kontur yang ditemukan dengan hardcode, perlu ditingkatkan)
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;
}