Jak wykryć długie krawędzie ściany, aby przygotować maskę i przebarwienie

Główną ideą jest umożliwienie użytkownikowi zmiany koloru na konkretny wybór użytkownika na podstawie ściany. Obecnie zaimplementowałem tę funkcję za pomocą cvFloodFill (pomaga przygotować obraz maski), który może pomóc mi zmienić względną wartość HSV dla ściany, abym mógł zachować krawędzie. ale problem z tym rozwiązaniem jest to, że działa na kolor i wszystkie ściany są przemalowane zamiast jednej ściany wybranej przez użytkownika.

Próbowałem również canny edge detection, ale po prostu był w stanie wykryć krawędź, ale nie był w stanie przekonwertować jej na obszar.

Proszę znaleźć poniższy kod, którego obecnie używam do funkcji repaint

  1. Przygotuj maskÄ™

    cvFloodFill(mask, new CvPoint(295, 75), new CvScalar(255, 255, 255,0), cvScalarAll(1), cvScalarAll(1), null, 4, null);

  2. Split channel

    cvSplit(hsvImage, hChannel, sChannel, vChannel, null);

  3. Zmień kolor

    cvAddS(vChannel, new CvScalar(255*(0.76-0.40),0,0,0), vChannel, mask);

Jak możemy wykryć krawędzie i odpowiedni obszar z obrazu.

Szukam rozwiązania, które może być inne niż opencv ale powinno być możliwe dla iPhone ' a i Androida

Przykładowy obraz

Edit

Jestem w stanie osiągnąć pewien wynik, jak na poniższym obrazku, używając poniższych kroków

cvCvtColor(image, gray, CV_BGR2GRAY);   
cvSmooth(gray,smooth,CV_GAUSSIAN,7,7,0,0);
cvCanny(smooth, canny, 10, 250, 5);

Są dwa problemy z tym wyjściem, Nie wiem, jak je rozwiązać 1. blisko brzegów 2. Usuń małe krawędzie

Tutaj wpisz opis obrazka

Author: Jigar Parekh, 2013-04-19

5 answers

Myślę, że mam rozwiązanie dla Ciebie! Istnieje przykładowy plik o nazwie watershed.cpp w OpenCV, po prostu go Uruchom, a otrzymasz taki wynik:

Tylko krótkie linie klawiaturowe

Możesz sprawić, że twój użytkownik narysuje na swoim ekranie, aby rozróżnić każdą ścianę. Następnie, jeśli chcesz czegoś bardziej precyzyjnego, możesz nakreślić obszary (bez dotykania innych linii) w następujący sposób:

Lepszy zarys

I TADA! :

Całkiem dobry wynik ;)

Przy odrobinie pracy możesz uczynić go przyjaznym dla użytkownika (anuluj ostatnią linię, połącz obszary itp...)

Mam nadzieję, że to pomoże!

 8
Author: Thom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-27 15:25:58

Możesz spróbować czegoś takiego:

 Mat imageOut = Mat::zeros(imageIn.rows, imageIn.cols, CV_8UC3);

 vector<vector<Point> > contours;
 vector<Vec4i> hierarchy;    

 findContours( imageIn, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
 for( int idx = 0; idx >= 0; idx = hierarchy[idx][0] )
 {
     Scalar color( rand()&255, rand()&255, rand()&255 );
     drawContours( imageOut, contours, idx, color, CV_FILLED, 8, hierarchy );
 }

Powinien rysować ściany w różnych kolorach. Jeśli to działa, oznacza to ,że w" hierarchii " każda ściana jest identyfikowana jako kontur, będziesz musiał dowiedzieć się, który użytkownik wybrał na swoim ekranie dotykowym i wykonać przetwarzanie kolorów.

Być może będziesz musiał zmienić różne parametry w linku" findContours " . Musisz również wygładzić obraz wejściowy przed wykryciem konturu, aby uniknąć zirytowania szczegóły lub tekstury.

Hope that helps, Tomasz

 10
Author: Thom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-24 14:03:05

Myślę, że możesz użyć algorytmu Canny Edge Detection, aby znaleźć różnicę krawędzi. Niektóre linki

  1. StackOverFlow
  2. StackOverFlow
  3. OpenCV QA
  4. OpenCV
  5. Native Tutorial
Mam nadzieję, że to ci pomoże. Dzięki.
 3
Author: Community,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:53:26

Oto kod OpenCV4Android, aby znaleźć największy kontur w Mat o nazwie image, który założymy, że znajduje się w przestrzeni kolorów RGBA. Aby znaleźć kontury, najpierw należy progować lub binaryzować obraz (przekonwertować na czarno-biały). Użycie rozmycia Gaussa na obrazie przed progiem zmniejsza liczbę wytwarzanych małych konturów. Parametry rozmiaru rozmycia i progu muszą być liczbami nieparzystymi; możesz się pobawić, aby dowiedzieć się, która wartość daje najlepsze wyniki (tutaj, Użyłem 7 dla obu).

List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat BW = new Mat();
Mat hierarchy = new Mat();
MatOfPoint largestContour;

Imgproc.cvtColor(image, image, Imgproc.COLOR_RGBA2GRAY); // convert to grayscale

Imgproc.GaussianBlur(image, BW, new Size(7,7), 0); 

Imgproc.adaptiveThreshold(BW, BW, 255, 
    Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 7, 2.0);

Imgproc.findContours(BW, contours, hierarchy, Imgproc.RETR_EXTERNAL,
        Imgproc.CHAIN_APPROX_SIMPLE);

double maxArea = 0;
for (MatOfPoint contour : contours) {
    double area = Imgproc.contourArea(contour);
    if (area > maxArea) {
        maxArea = area;
        largestContour = contour;
    }
}
 2
Author: 1'',
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-25 03:46:14

Są dwa problemy z tym wyjściem, Nie wiem, jak je rozwiązać 1. blisko krawędzi 2. Usuń małe krawędzie

  1. Możesz użyć operacji morfologicznych, aby zamknąć krawędzie. Poszukaj operatorów dylatacyjnych i zamykających.

  2. Małe krawędzie można usunąć, wykonując etykietowanie. Policz liczbę pikseli w każdym regionie(połączone białe piksele). Usuń dowolny obszar o liczbie pikseli mniejszej niż określony próg. Nie używam opencv, ale większość biblioteki mają funkcję etykietowania, która tworzy obraz, w którym każdemu zestawowi dotykających pikseli jednego koloru przypisany jest unikalny kolor w obrazie wyjściowym.

 0
Author: denver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-27 04:04:27