द्विआधारी छवि पर मोटी रेखाओं को ओवरलैप करते हुए सेगमेंटिंग

Aug 16 2020

मेरे पास एक द्विआधारी छवि है जैसा कि मूल छवि पर विभिन्न प्रीप्रोसेसिंग और डिटेक्शन पाइपलाइनों को लागू करने के बाद दिखाया गया है।

जैसा कि तस्वीर में देखा गया है कि विमानों के लिए वास्तव में 2 रनवे (टरमैक) हैं जो एक चौराहे पर एक दूसरे को पार कर रहे हैं। मुझे दोनों रनवे को विभाजित करने और अपने कंट्रो को वापस करने की आवश्यकता है। मैं समोच्च सुविधाओं के बारे में opencv कार्यों की जाँच की है, लेकिन कोई भाग्य नहीं था। cv2.fitLineठीक लगता है, लेकिन यह केवल तभी काम करता है जब समोच्च में केवल एक ही रेखा हो। मास्क लगाते समय परिणामी छवि इस प्रकार दिखनी चाहिए:

जवाब

3 MarkSetchell Aug 30 2020 at 23:17

यहाँ एक संभव दृष्टिकोण, बस के साथ टर्मिनल में किया है ImageMagick , लेकिन आप काफी के साथ अजगर में भी ऐसा ही करने में सक्षम होना चाहिए वैंड या साथ scikit छवि और medial_axis ।

सबसे पहले, चित्र को कंकाल करें:

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

फिर 130 पिक्सल से अधिक लंबी लाइनों की तलाश में "हफ लाइन डिटेक्शन" चलाएं और सारणीबद्ध रूप में परिणाम पूछें:

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

उत्पादन

# 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

इसका मतलब है कि यह 2 लाइनों का पता लगाया है:

  • एक लाइन 297,0 से निर्देशांक 286,589 का समन्वय करता है, ऊर्ध्वाधर = 255 पिक्सल 1 डिग्री से ऊर्ध्वाधर तक
  • 0,591 से 464,333 को निर्देशांक करने के लिए निर्देशांक की एक पंक्ति, लंबाई = 189 पिक्सेल के साथ 61 डिग्री से ऊर्ध्वाधर तक

बस उदाहरण के लिए, मैं पहला लाल रंग में दूंगा और दूसरा हरे रंग में:

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

कीवर्ड : पायथन, इमेज प्रोसेसिंग, कंकाल, कंकाल, थिनिंग, रनवे, रनवे, चौराहा, हूप लाइन डिटेक्शन।

2 sturkmen Aug 30 2020 at 21:19

मैंने अपने पुराने उत्तर को संदर्भित करते हुए C ++ के साथ आपकी समस्या को हल करने की कोशिश की ।

कुछ कदम:

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

द्विआधारी छवि की दो प्रतिलिपि बनाएं और दोष बिंदुओं का उपयोग करके रेखाएं बनाएं

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

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