İkili bir görüntüde üst üste binen kalın çizgileri bölümleme

Aug 16 2020

Orijinal görüntüye çeşitli ön işleme ve algılama boru hatlarını uyguladıktan sonra aşağıda gösterildiği gibi bir ikili görüntüm var.

Resimde görüldüğü gibi, bir kesişme bölgesinde birbirini geçen uçaklar için aslında 2 pist (asfalt) bulunmaktadır. İhtiyacım olan şey, her iki pisti de bölmek ve konturlarına geri dönmek. Kontur özellikleriyle ilgili opencv işlevlerini kontrol ettim ama hiç şansım olmadı. cv2.fitLineiyi görünüyor, ancak yalnızca konturda tek bir çizgi varsa işe yarar. Maskeler uygulandığında ortaya çıkan görüntü şu şekilde görünmelidir:

Yanıtlar

3 MarkSetchell Aug 30 2020 at 23:17

Aşağıda ImageMagick ile Terminal'de yapılan olası bir yaklaşım var, ancak Wand ile Python'da veya scikit-image ve medial_axis ile hemen hemen aynı şeyi yapabilmelisiniz .

İlk olarak, görüntüyü iskeletleştirin:

magick runways.png -threshold 50% -morphology Thinning:-1 Skeleton skeleton.png

Ardından 130 pikselden daha uzun çizgileri arayan bir "Hough Line Detection" çalıştırın ve sonuçları tablo biçiminde isteyin:

magick skeleton.png -hough-lines 9x9+130 mvg:-

Çıktı

# 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

Bu, 2 hat algıladığı anlamına gelir:

  • 297,0 koordinatlarından 286,589 koordinatlarına kadar bir çizgi, uzunluk = 255 piksel dikey olarak 1 derece
  • 0,591 koordinatlarından 464,333 koordinatlarına kadar bir çizgi, uzunluk = 189 piksel düşeye 61 derece

Sadece örneklendirmek için, birincisini kırmızı, ikincisini yeşil çizeceğim:

magick runways.png                       \
   -fill red  -draw "line 297,0 286,589" \
   -fill lime -draw "line 0,591 464,333" result.png

Anahtar Kelimeler : Python, görüntü işleme, iskelet, iskeletleştirme, inceltme, pist, pistler, kavşak, Hough Hattı Tespiti.

2 sturkmen Aug 30 2020 at 21:19

Sorununuzu eski cevabıma referansla C ++ ile çözmeye çalıştım .

bazı adımlar:

--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);

ikili görüntünün iki kopyasını oluşturun ve kusur noktalarını kullanarak çizgiler çizin

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);

görüntülerden konturları bulun ve çizin (bulunan kontur indeksini kodladım, iyileştirilmesi gerekiyor)

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;
}