Я использовал метод findcontours()
для извлечения контура из изображения, но я понятия не имею, как вычислить кривизну из набора точек контура. Может кто-нибудь мне помочь? Большое спасибо!Как вычислить кривизну выделенного контура opencv?
ответ
Для меня кривизна:
t
где находится положение внутри контура и x(t)
соответственно. y(t)
вернуть соответствующие x
соответственно. y
значение. См. here.
Так, согласно моему определению кривизны, можно реализовать это следующим образом:
std::vector<float> vecCurvature(vecContourPoints.size());
cv::Point2f posOld, posOlder;
cv::Point2f f1stDerivative, f2ndDerivative;
for (size_t i = 0; i < vecContourPoints.size(); i++)
{
const cv::Point2f& pos = vecContourPoints[i];
if (i == 0){ posOld = posOlder = pos; }
f1stDerivative.x = pos.x - posOld.x;
f1stDerivative.y = pos.y - posOld.y;
f2ndDerivative.x = - pos.x + 2.0f * posOld.x - posOlder.x;
f2ndDerivative.y = - pos.y + 2.0f * posOld.y - posOlder.y;
float curvature2D = 0.0f;
if (std::abs(f2ndDerivative.x) > 10e-4 && std::abs(f2ndDerivative.y) > 10e-4)
{
curvature2D = sqrt(std::abs(
pow(f2ndDerivative.y*f1stDerivative.x - f2ndDerivative.x*f1stDerivative.y, 2.0f)/
pow(f2ndDerivative.x + f2ndDerivative.y, 3.0)));
}
vecCurvature[i] = curvature2D;
posOlder = posOld;
posOld = pos;
}
Он работает на незамкнутых pointlists, а также. Для закрытых контуров вы можете изменить поведение границы (для первых итераций).
ОБНОВЛЕНИЕ:
Объяснение для производных:
Производное для непрерывного 1 одномерной функции f(t)
является:
Но мы в дискретном пространстве и имеют две дискретные функции f_x(t)
и f_y(t)
, где наименьший шаг для t
- один.
Вторая производная является производной от первой производной:
Используя приближение первой производной, он уступает:
Существуют другие приближения для производных, если y ou google, вы найдете много.
Хотя теория ответа Гомбата верна, в коде есть и ошибки, а также в формулах (знаменатель t+n-x
должен быть t+n-t
).Я сделал несколько изменений:
- использует симметричные производные, чтобы получить более точное расположение кривизны максимумов
- позволяют использовать размер шага для производной расчета (может быть использована для уменьшения шума от шумных контуров)
- работы с закрытыми контурами
Исправления: * возвращение бесконечности, как кривизна, если знаменатель равен 0 (не 0) * добавлен квадратный расчет в знаменателе * правильная проверка для 0 делителя
std::vector<double> getCurvature(std::vector<cv::Point> const& vecContourPoints, int step)
{
std::vector<double> vecCurvature(vecContourPoints.size());
if (vecContourPoints.size() < step)
return vecCurvature;
auto frontToBack = vecContourPoints.front() - vecContourPoints.back();
std::cout << CONTENT_OF(frontToBack) << std::endl;
bool isClosed = ((int)std::max(std::abs(frontToBack.x), std::abs(frontToBack.y))) <= 1;
cv::Point2f pplus, pminus;
cv::Point2f f1stDerivative, f2ndDerivative;
for (int i = 0; i < vecContourPoints.size(); i++)
{
const cv::Point2f& pos = vecContourPoints[i];
int maxStep = step;
if (!isClosed)
{
maxStep = std::min(std::min(step, i), (int)vecContourPoints.size()-1-i);
if (maxStep == 0)
{
vecCurvature[i] = std::numeric_limits<double>::infinity();
continue;
}
}
int iminus = i-maxStep;
int iplus = i+maxStep;
pminus = vecContourPoints[iminus < 0 ? iminus + vecContourPoints.size() : iminus];
pplus = vecContourPoints[iplus > vecContourPoints.size() ? iplus - vecContourPoints.size() : iplus];
f1stDerivative.x = (pplus.x - pminus.x)/(iplus-iminus);
f1stDerivative.y = (pplus.y - pminus.y)/(iplus-iminus);
f2ndDerivative.x = (pplus.x - 2*pos.x + pminus.x)/((iplus-iminus)/2*(iplus-iminus)/2);
f2ndDerivative.y = (pplus.y - 2*pos.y + pminus.y)/((iplus-iminus)/2*(iplus-iminus)/2);
double curvature2D;
double divisor = f1stDerivative.x*f1stDerivative.x + f1stDerivative.y*f1stDerivative.y;
if (std::abs(divisor) > 10e-8)
{
curvature2D = std::abs(f2ndDerivative.y*f1stDerivative.x - f2ndDerivative.x*f1stDerivative.y)/
pow(divisor, 3.0/2.0) ;
}
else
{
curvature2D = std::numeric_limits<double>::infinity();
}
vecCurvature[i] = curvature2D;
}
return vecCurvature;
}
- 1. opencv in python: Есть ли простой способ вычислить кривизну контура?
- 2. Matlab - вычислить кривизну вдоль упорядоченного периметра
- 3. Вычислить кривизну для 3 точек (x, y)
- 4. Вычислить кривизну из smooth.spline в R
- 5. Java OpenCV, контур контура
- 6. Минимальное расположение контура контура OpenCV в python
- 7. Ориентация контура OpenCV
- 8. Развитие контура OpenCV
- 9. Выбор контура в OpenCV
- 10. Поиск области контура OpenCV
- 11. Ошибка контура Opencv
- 12. Как вычислить кривизну кода цепи при обработке изображений?
- 13. OpenCV - Как перевести контур контура в контур контура
- 14. сглаживающие острые углы контура OpenCV
- 15. Закрытие кривой контура в OpenCV
- 16. OpenCV - определение контуров контура тела
- 17. OpenCV, уравнять гистограмму контура изображения
- 18. Поиск длины контура в opencv
- 19. OpenCV: получение цвета центра контура
- 20. Определение цвета внутри контура OpenCV
- 21. OpenCV - Поиск конечных точек контура?
- 22. Позиция контура обнаружения объекта OpenCV
- 23. OpenCV: Как найти цвет внутри контура/полигона?
- 24. Как совместить два контура в opencv?
- 25. Как получить центр масс контура? Android opencv
- 26. Opencv: как вычислить трехмерную гистограмму?
- 27. Рассчитать центр контура/Область
- 28. найти кривизну на карте глубины
- 29. Вычислить расстояние (неравенство) OpenCV
- 30. вычислить автоэкспозицию в openCv
Это очень поможет, если вы предоставите нам список вещей, которые вы уже пробовали, и с более конкретным вопросом. – YePhIcK