Виявлення різних компонентів:
Якщо ви намагаєтесь виявити різні компоненти, ймовірно, є інші підходи до їх виконання, ніж виявлення контурів. Ось приклад у Mathematica. Ерозія з подальшим розширенням використовується для закриття проміжку у другому компоненті до виявлення (якщо ви цього не зробите, він не виявить).
img = Binarize@Import["http://i.stack.imgur.com/yqDyu.png"];
Colorize[MorphologicalComponents[Dilation[Erosion[img,1],1]]]
На рисунку зліва внизу показано виявлення недосконалого об'єкта (не закриваючи пробіл) і праворуч показано правильне виявлення (працює вищевказаний код).
Виявлення різних контурів:
Однак, якщо ви дійсно хочете розділити лише контури, ось приклад. Ерозія та дилатація виконуються, як і раніше, щоб закрити проміжок, і отримане зображення пропускається через детектор краю Canny. Я зробив параметри за замовчуванням явними, щоб ви могли бачити, що використовується.
img2 = EdgeDetect[Dilation[Erosion[img, 1], 1], Method -> "Canny"]
Це дасть вам як внутрішній, так і зовнішній край (див. Малюнок зліва внизу), оскільки ширина пікселя більша за 1 навколо. У мене не було великої удачі, намагаючись зменшити його, оскільки продуктивність погіршується (може відрізнятися від інших ваших зображень). Внутрішні контури - це ті, що вам потрібно, а зовнішній контур - це просто комбінований контур усіх 4 компонентів. Тепер все, що нам потрібно зробити, це скинути самий зовнішній:
SelectComponents[img2, "EnclosingComponentCount", # > 0 &]
що дає лише внутрішні контури (див. праворуч внизу). Іншими словами, він підбирає лише ті контури, які укладені хоча б одним іншим контуром, який автоматично дискваліфікує зовнішній. Я не знаю еквівалента цих команд / операцій у openCV.
Зауважте, що видимі розриви фігури пов'язані із збереженням jpeg у меншому розмірі. Це не так виглядає на моєму екрані.