Wykrywanie różnych komponentów:
Jeśli próbujesz wykryć różne komponenty, prawdopodobnie istnieją inne podejścia do ich wykonania niż wykrywanie konturów. Oto przykład w Mathematica. Erozja, po której następuje dylatacja, służy do zamknięcia luki w drugim składniku przed wykryciem (jeśli tego nie zrobisz, nie wykryje go).
img = Binarize@Import["http://i.stack.imgur.com/yqDyu.png"];
Colorize[MorphologicalComponents[Dilation[Erosion[img,1],1]]]
Poniższy rysunek po lewej pokazuje niedoskonałe wykrywanie obiektów (bez zamykania szczeliny), a po prawej pokazuje prawidłowe wykrywanie (uruchomienie powyższego kodu).
Wykrywanie różnych konturów:
Jeśli jednak naprawdę chcesz oddzielić tylko kontury, oto przykład. Erozja i dylatacja są wykonywane jak poprzednio w celu zamknięcia luki, a powstały obraz jest przepuszczany przez detektor krawędzi Canny. Podałem wyraźne opcje domyślne, abyś mógł zobaczyć, co jest używane.
img2 = EdgeDetect[Dilation[Erosion[img, 1], 1], Method -> "Canny"]
To da ci zarówno wewnętrzną, jak i zewnętrzną krawędź (patrz rysunek po lewej poniżej), ponieważ szerokość piksela jest większa niż 1 wokół. Nie miałem dużo szczęścia, próbując go rozrzedzić, ponieważ wydajność spada (może się różnić w przypadku innych obrazów). Kontury wewnętrzne są tymi, które chcesz, a kontur zewnętrzny to tylko kontur wszystkich 4 elementów. Teraz wszystko, co musimy zrobić, to upuścić najbardziej zewnętrzny z:
SelectComponents[img2, "EnclosingComponentCount", # > 0 &]
który daje tylko wewnętrzne kontury (patrz dolny prawy róg). Innymi słowy, wybiera tylko te kontury, które są otoczone przez co najmniej jeden inny kontur, co automatycznie dyskwalifikuje najbardziej zewnętrzny. Nie znam odpowiednika tych poleceń / operacji w openCV.
Zauważ, że pozorne przerwy na rysunku wynikają z zapisania do formatu JPEG w mniejszym rozmiarze. Nie wygląda tak na moim ekranie.