mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-18 00:01:17 +08:00
Merge pull request #3322 from MisakiCoca:ellipse
This commit is contained in:
@@ -16,3 +16,4 @@ Extended Image Processing
|
||||
- Pei&Lin Normalization
|
||||
- Ridge Detection Filter
|
||||
- Binary morphology on run-length encoded images
|
||||
- Ellipse Detector
|
||||
|
@@ -389,3 +389,14 @@ pages={617--632},
|
||||
year={2021},
|
||||
publisher={Springer}
|
||||
}
|
||||
|
||||
@article{jia2017fast,
|
||||
title={A fast ellipse detector using projective invariant pruning},
|
||||
author={Jia, Qi and Fan, Xin and Luo, Zhongxuan and Song, Lianbo and Qiu, Tie},
|
||||
journal={IEEE Transactions on Image Processing},
|
||||
volume={26},
|
||||
number={8},
|
||||
pages={3665--3679},
|
||||
year={2017},
|
||||
publisher={IEEE}
|
||||
}
|
@@ -62,6 +62,7 @@
|
||||
#include "ximgproc/edgepreserving_filter.hpp"
|
||||
#include "ximgproc/color_match.hpp"
|
||||
#include "ximgproc/radon_transform.hpp"
|
||||
#include "ximgproc/find_ellipses.hpp"
|
||||
|
||||
|
||||
/** @defgroup ximgproc Extended Image Processing
|
||||
|
38
modules/ximgproc/include/opencv2/ximgproc/find_ellipses.hpp
Normal file
38
modules/ximgproc/include/opencv2/ximgproc/find_ellipses.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef __OPENCV_FIND_ELLIPSES_HPP__
|
||||
#define __OPENCV_FIND_ELLIPSES_HPP__
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
|
||||
namespace cv {
|
||||
namespace ximgproc {
|
||||
|
||||
//! @addtogroup ximgproc
|
||||
//! @{
|
||||
|
||||
/**
|
||||
@brief Finds ellipses fastly in an image using projective invariant pruning.
|
||||
*
|
||||
* The function detects ellipses in images using projective invariant pruning.
|
||||
* For more details about this implementation, please see
|
||||
* [JIA2017FAST] Jia, Qi et al, (2017).
|
||||
* A Fast Ellipse Detector using Projective Invariant Pruning. IEEE Transactions on Image Processing.
|
||||
*
|
||||
@param image input image, could be gray or color.
|
||||
@param ellipses output vector of found ellipses. each vector is encoded as five float $x, y, a, b, radius, score$.
|
||||
@param scoreThreshold float, the threshold of ellipse score.
|
||||
@param reliabilityThreshold float, the threshold of reliability.
|
||||
@param centerDistanceThreshold float, the threshold of center distance.
|
||||
*/
|
||||
CV_EXPORTS_W void findEllipses(
|
||||
InputArray image, OutputArray ellipses,
|
||||
float scoreThreshold = 0.7f, float reliabilityThreshold = 0.5f,
|
||||
float centerDistanceThreshold = 0.05f
|
||||
);
|
||||
//! @} ximgproc
|
||||
}
|
||||
}
|
||||
#endif
|
27
modules/ximgproc/perf/perf_find_ellipses.cpp
Normal file
27
modules/ximgproc/perf/perf_find_ellipses.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "perf_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
typedef tuple<Size, MatType, int> FindEllipsesTestParam;
|
||||
typedef TestBaseWithParam<FindEllipsesTestParam> FindEllipsesTest;
|
||||
|
||||
PERF_TEST_P(FindEllipsesTest, perf, Combine(SZ_TYPICAL, Values(CV_8U), Values(1, 3)))
|
||||
{
|
||||
FindEllipsesTestParam params = GetParam();
|
||||
Size sz = get<0>(params);
|
||||
int matType = get<1>(params);
|
||||
int srcCn = get<2>(params);
|
||||
|
||||
Mat src(sz, CV_MAKE_TYPE(matType, srcCn));
|
||||
Mat dst(sz, CV_32FC(6));
|
||||
|
||||
declare.in(src, WARMUP_RNG).out(dst);
|
||||
|
||||
TEST_CYCLE() findEllipses(src, dst, 0.7f, 0.5f, 0.05f);
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
}} // namespace
|
50
modules/ximgproc/samples/find_ellipses.cpp
Normal file
50
modules/ximgproc/samples/find_ellipses.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include <iostream>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
#include <opencv2/ximgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
using namespace cv;
|
||||
|
||||
int main() {
|
||||
|
||||
// load image
|
||||
Mat img = imread(samples::findFile("stuff.jpg"), IMREAD_COLOR);
|
||||
|
||||
// check if image is loaded
|
||||
if (img.empty()) {
|
||||
std::cout << "fail to open image" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// create output array
|
||||
std::vector<Vec6f> ells;
|
||||
|
||||
// test ellipse detection
|
||||
cv::ximgproc::findEllipses(img, ells, 0.4f, 0.7f, 0.02f);
|
||||
|
||||
// print output
|
||||
for (unsigned i = 0; i < ells.size(); i++) {
|
||||
Vec6f ell = ells[i];
|
||||
std::cout << ell << std::endl;
|
||||
Scalar color(0, 0, 255);
|
||||
// draw ellipse on image
|
||||
ellipse(
|
||||
img,
|
||||
Point(cvRound(ell[0]), cvRound(ell[1])),
|
||||
Size(cvRound(ell[2]), cvRound(ell[3])),
|
||||
ell[5] * 180 / CV_PI, 0.0, 360.0, color, 3
|
||||
);
|
||||
}
|
||||
|
||||
// show image
|
||||
imshow("result", img);
|
||||
waitKey();
|
||||
|
||||
// end
|
||||
return 0;
|
||||
}
|
1988
modules/ximgproc/src/find_ellipses.cpp
Normal file
1988
modules/ximgproc/src/find_ellipses.cpp
Normal file
File diff suppressed because it is too large
Load Diff
43
modules/ximgproc/test/test_find_ellipses.cpp
Normal file
43
modules/ximgproc/test/test_find_ellipses.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
|
||||
TEST(FindEllipsesTest, EllipsesOnly)
|
||||
{
|
||||
std::string picture_name = "cv/imgproc/stuff.jpg";
|
||||
std::string filename = cvtest::TS::ptr()->get_data_path() + picture_name;
|
||||
Mat src = imread(filename, IMREAD_GRAYSCALE);
|
||||
EXPECT_FALSE(src.empty()) << "Invalid test image: " << filename;
|
||||
|
||||
std::vector<Vec6f> ells;
|
||||
ximgproc::findEllipses(src, ells, 0.7f, 0.75f, 0.02f);
|
||||
|
||||
// number check
|
||||
EXPECT_EQ(ells.size(), size_t(3)) << "Should find 3 ellipses";
|
||||
|
||||
// position check
|
||||
// target centers
|
||||
Point2f center_1(226.9, 57.2);
|
||||
Point2f center_2(393.1, 187.0);
|
||||
Point2f center_3(208.5, 307.5);
|
||||
// matching
|
||||
for (auto ell: ells) {
|
||||
bool has_match = false;
|
||||
for (auto c: {center_1, center_2, center_3}) {
|
||||
Point2f diff = c - Point2f(ell[0], ell[1]);
|
||||
float distance = sqrt(diff.x * diff.x + diff.y * diff.y);
|
||||
if (distance < 5.0) {
|
||||
has_match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPECT_TRUE(has_match) << "Wrong ellipse center:" << Point2f(ell[0], ell[1]);
|
||||
}
|
||||
}
|
||||
}}
|
Reference in New Issue
Block a user