2016-06-10 3 views
0

Я использую OpenCV 2.4.13OpenCV найти периметр связной компоненты

Я пытаюсь найти периметр связной компоненты, я думал об использовании ConnectedComponentWithStats но он не возвращает периметр, только площадь, ширина и т. д. Существует метод, чтобы найти область с контуром, но не наоборот (с одним компонентом я имею в виду не все изображение).

Метод arcLength не работает, потому что у меня есть все точки компонента, а не только контур.

Я знаю, что есть способ BF найти его, итерации через каждый пиксель компонента и посмотреть, есть ли у него соседи, которые не находятся в одном компоненте. Но мне нужна функция, которая стоит меньше. В противном случае, если вы знаете способ связать компонент с контурами, найденными методом findContours, мне это тоже подходит.

Благодаря

+0

Там нет никакой разницы между контур и подключенный компонент, можете ли вы загрузить входное изображение? –

+0

Связанный компонент также имеет пиксели внутри контура no? – Akainiro

ответ

0

Проще всего, вероятно, чтобы использовать findContours.

Вы можете вычислить контур на i-м компоненте, вычисленный connectedComponents(WithStats), так что они выровнены с вашими ярлыками. Используя CHAIN_APPROX_NONE, вы получите все точки в контуре, поэтому вектор size() уже является мерилом периметра. Вы можете в конечном итоге использовать arcLength(...), чтобы получить более точный результат:

Mat1i labels; 
int n_labels = connectedComponents(img, labels); 

for (int i = 1; i < n_labels; ++i) 
{ 
    // Get the mask for the i-th contour 
    Mat1b mask_i = labels == i; 

    // Compute the contour 
    vector<vector<Point>> contours;  
    findContours(mask_i.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); 

    if (!contours.empty()) 
    { 
     // The first contour (and probably the only one) 
     // is the one you're looking for 

     // Compute the perimeter 
     double perimeter_i = contours[0].size(); 
    } 
} 
+0

Хорошо, я не знал, что могу использовать findContours по определенному компоненту с маской, спасибо! – Akainiro

+0

Рад, что это помогло: D – Miki

+0

Вопрос: почему вы использовали mask_i.clone()? Недостаточно ли mask_i? – Akainiro

0

Добавление к @ ответ Мики, это более быстрый способ найти периметр связной компоненты

//getting the connected components with statistics 
cv::Mat1i labels, stats; 
cv::Mat centroids; 

int lab = connectedComponentsWithStats(img, labels, stats, centroids); 

for (int i = 1; i < lab; ++i) 
{ 
    //Rectangle around the connected component 
    cv::Rect rect(stats(i, 0), stats(i, 1), stats(i, 2), stats(i, 3)); 

    // Get the mask for the i-th contour 
    Mat1b mask_i = labels(rect) == i; 

    // Compute the contour 
    vector<vector<Point>> contours;  
    findContours(mask_i, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE); 

    if(contours.size() <= 0) 
     continue;   

    //Finding the perimeter 
    double perimeter = contours[0].size(); 
    //you can use this as well for measuring perimeter 
    //double perimeter = arcLength(contours[0], true); 

} 
Смежные вопросы