OpenCV найти периметр подключенного компонента

Я использую OpenCV 2.4.13

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

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

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

Спасибо

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();
}
}
1

Другие решения

Добавляя к ответу @ Miki, это более быстрый способ найти периметр подключенного компонента.

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

}
1

По вопросам рекламы [email protected]