Użyłem metody findcontours()
, aby wyodrębnić kontur z obrazu, ale nie mam pojęcia, jak obliczyć krzywiznę z zestawu punktów konturu. Czy ktoś może mi pomóc? Dziękuję Ci bardzo!Jak mogę obliczyć krzywiznę wyodrębnionego konturu przez opencv?
Odpowiedz
Dla mnie krzywizna jest:
t
gdzie jest pozycja wewnątrz konturu i x(t)
wzgl. y(t)
zwróć odpowiednią odpowiedź x
lub y
wartość. Zobacz here.
Więc, według mojej definicji krzywizny, można wdrożyć go w ten sposób:
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;
}
działa na niezamkniętych pointlists również. W przypadku zamkniętych konturów może zajść potrzeba zmiany zachowania granicy (dla pierwszych iteracji).
UPDATE:
wyjaśnienie pochodne:
Pochodna nieprzerwanie 1 funkcją wymiarów f(t)
jest:
ale jesteśmy w dyskretnym miejscu i mieć dwie dyskretne funkcje f_x(t)
i gdzie najmniejszy krok dla t
to jeden.
Druga pochodna jest pochodną pierwszej pochodnej:
Stosując przybliżenie pierwszej pochodnej, to otrzymuje się:
Istnieją inne przybliżenia dla instrumentów pochodnych, jeżeli y ou google, znajdziesz dużo.
Podczas gdy teoria stojąca za odpowiedzią Gombata jest poprawna, występują pewne błędy w kodzie, jak również we wzorach (mianownik t+n-x
powinien być t+n-t
).Dokonaniu kilku zmian:
- stosowanie pochodnych symetryczne, aby uzyskać bardziej precyzyjne rozmieszczenie krzywizny maksimów
- pozwala na użycie wielkości kroku kalkulacji pochodnej (może być stosowany w celu ograniczenia hałasu z głośnym kontury)
- prace przy zamkniętych konturów
rozwiązania: * powrotu nieskończoności, gdy krzywizna mianownikiem jest 0 (brak 0) * dodano kwadratowy obliczenia w mianowniku * prawidłowe kontrola 0 dzielnik
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 || podobieństwo konturu
- 2. Jak mogę obliczyć obszar wewnątrz konturu w R?
- 3. Python OpenCV Drzewo hierarchii konturu
- 4. Jak przyciąć wewnętrzny obszar konturu?
- 5. Tworzenie własnego konturu w opencv przy użyciu pythona
- 6. Obliczyć Gęste funkcje SIFT w OpenCV 3.0
- 7. Jak obliczyć maksymalną wartość pikseli Mat w OpenCV
- 8. Jak obliczyć histogramy lokalnego kodu binarnego za pomocą OpenCV?
- 9. Jak mogę uzyskać wartości (x, y) linii wykreślonej przez wykres konturu?
- 10. Jak mogę ponownie obliczyć wspólny wykładnik?
- 11. Znajdowanie obróconego prostokąta od konturu
- 12. Jak rozpoznać kontury w obrębie innego konturu za pomocą JavaCV?
- 13. Jak korzystać z modelu tensorflow wyodrębnionego z przeszkolonego modelu kerasów?
- 14. Jak wygładzić kontur konturu matplotlib?
- 15. Jak mogę obliczyć różnicę między dwoma ciągami?
- 16. Jak mogę obliczyć medianę wartości w SQLite?
- 17. Momenty OpenCV Contours?
- 18. Jak sprawdzić bliskość konturu obiektu QGraphicsPathItem?
- 19. OpenCV C++: Sortowanie konturów według ich konturuArea
- 20. Obliczanie powierzchni obiektu za pomocą OpenCV
- 21. Polarny wykres konturu w Matplotlib
- 22. Jak obliczyć wyniki?
- 23. Jak obliczyć FAT
- 24. Jak mogę obliczyć liczbę lat między dwiema datami?
- 25. Jak obliczyć środek elipsy przez dwa punkty i rozmiary promienia
- 26. Crop Rectangle zwrócony przez minAreaRect OpenCV [Python]
- 27. FPS jak to obliczyć?
- 28. Jak mogę obliczyć sygnaturę interfejsu AWS (v4) w pythonie?
- 29. Używanie kamery niestandardowej w OpenCV (przez GStreamer)
- 30. Jak uruchomić kod OpenCV bez OpenCv Manager
Pomogłoby to ogromnie, gdybyś przedstawił nam listę rzeczy, które już wypróbowałeś i bardziej szczegółowe pytania. – YePhIcK