mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
496 lines
12 KiB
496 lines
12 KiB
// 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" |
|
//#include "opencv2/imgproc/segmentation.hpp" |
|
|
|
namespace opencv_test { namespace { |
|
|
|
|
|
Mat getTestImageGray() |
|
{ |
|
static Mat m; |
|
if (m.empty()) |
|
{ |
|
m = imread(findDataFile("shared/lena.png"), IMREAD_GRAYSCALE); |
|
} |
|
return m.clone(); |
|
} |
|
|
|
Mat getTestImageColor() |
|
{ |
|
static Mat m; |
|
if (m.empty()) |
|
{ |
|
m = imread(findDataFile("shared/lena.png"), IMREAD_COLOR); |
|
} |
|
return m.clone(); |
|
} |
|
|
|
Mat getTestImage1() |
|
{ |
|
static Mat m; |
|
if (m.empty()) |
|
{ |
|
m.create(Size(200, 100), CV_8UC1); |
|
m.setTo(Scalar::all(128)); |
|
Rect roi(50, 30, 100, 40); |
|
m(roi).setTo(Scalar::all(0)); |
|
#if 0 |
|
imshow("image", m); |
|
waitKey(); |
|
#endif |
|
} |
|
return m.clone(); |
|
} |
|
|
|
Mat getTestImage2() |
|
{ |
|
static Mat m; |
|
if (m.empty()) |
|
{ |
|
m.create(Size(200, 100), CV_8UC1); |
|
m.setTo(Scalar::all(128)); |
|
Rect roi(40, 30, 100, 40); |
|
m(roi).setTo(Scalar::all(255)); |
|
#if 0 |
|
imshow("image", m); |
|
waitKey(); |
|
#endif |
|
} |
|
return m.clone(); |
|
} |
|
|
|
Mat getTestImage3() |
|
{ |
|
static Mat m; |
|
if (m.empty()) |
|
{ |
|
m.create(Size(200, 100), CV_8UC1); |
|
m.setTo(Scalar::all(128)); |
|
Scalar color(0,0,0,0); |
|
line(m, Point(30, 50), Point(50, 50), color, 1); |
|
line(m, Point(50, 50), Point(80, 30), color, 1); |
|
line(m, Point(150, 50), Point(80, 30), color, 1); |
|
line(m, Point(150, 50), Point(180, 50), color, 1); |
|
|
|
line(m, Point(80, 10), Point(80, 90), Scalar::all(200), 1); |
|
line(m, Point(100, 10), Point(100, 90), Scalar::all(200), 1); |
|
line(m, Point(120, 10), Point(120, 90), Scalar::all(200), 1); |
|
#if 0 |
|
imshow("image", m); |
|
waitKey(); |
|
#endif |
|
} |
|
return m.clone(); |
|
} |
|
|
|
Mat getTestImage4() |
|
{ |
|
static Mat m; |
|
if (m.empty()) |
|
{ |
|
m.create(Size(200, 100), CV_8UC1); |
|
for (int y = 0; y < m.rows; y++) |
|
{ |
|
for (int x = 0; x < m.cols; x++) |
|
{ |
|
float dx = (float)(x - 100); |
|
float dy = (float)(y - 100); |
|
float d = sqrtf(dx * dx + dy * dy); |
|
m.at<uchar>(y, x) = saturate_cast<uchar>(100 + 100 * sin(d / 10 * CV_PI)); |
|
} |
|
} |
|
#if 0 |
|
imshow("image", m); |
|
waitKey(); |
|
#endif |
|
} |
|
return m.clone(); |
|
} |
|
|
|
Mat getTestImage5() |
|
{ |
|
static Mat m; |
|
if (m.empty()) |
|
{ |
|
m.create(Size(200, 100), CV_8UC1); |
|
for (int y = 0; y < m.rows; y++) |
|
{ |
|
for (int x = 0; x < m.cols; x++) |
|
{ |
|
float dx = (float)(x - 100); |
|
float dy = (float)(y - 100); |
|
float d = sqrtf(dx * dx + dy * dy); |
|
m.at<uchar>(y, x) = saturate_cast<uchar>(x / 2 + 100 * sin(d / 10 * CV_PI)); |
|
} |
|
} |
|
#if 0 |
|
imshow("image", m); |
|
waitKey(); |
|
#endif |
|
} |
|
return m.clone(); |
|
} |
|
|
|
void show(const Mat& img, const std::vector<Point> pts) |
|
{ |
|
if (cvtest::debugLevel >= 10) |
|
{ |
|
Mat dst = img.clone(); |
|
std::vector< std::vector<Point> > contours; |
|
contours.push_back(pts); |
|
polylines(dst, contours, false, Scalar::all(255)); |
|
imshow("dst", dst); |
|
waitKey(); |
|
} |
|
} |
|
|
|
Size estimateContourSize(const std::vector<Point>& pts) |
|
{ |
|
Size s(0,0); |
|
for (size_t i = 0; i < pts.size(); i++) |
|
{ |
|
if (s.width < pts[i].x) |
|
s.width = pts[i].x; |
|
if (s.height < pts[i].y) |
|
s.height = pts[i].y; |
|
} |
|
return s; |
|
} |
|
|
|
int contoursAreaPixelsMismatch(const std::vector<Point>& pts, const std::vector<Point>& gt) |
|
{ |
|
Size ptsSize = estimateContourSize(pts); |
|
Size gtSize = estimateContourSize(gt); |
|
|
|
Size imgSize(std::max(ptsSize.width, gtSize.width)+1, std::max(ptsSize.height, gtSize.height)+1); |
|
Mat ptsArea = Mat::zeros(imgSize, CV_8UC1); |
|
Mat gtArea = Mat::zeros(imgSize, CV_8UC1); |
|
|
|
std::vector<std::vector<Point>> pts_wrapped = {pts}; |
|
std::vector<std::vector<Point>> gt_wrapped = {gt}; |
|
drawContours(ptsArea, pts_wrapped, -1, Scalar(255), FILLED); |
|
drawContours(gtArea, gt_wrapped, -1, Scalar(255), FILLED); |
|
|
|
Mat uni = ptsArea | gtArea; |
|
Mat intersection = ptsArea & gtArea; |
|
bitwise_not(intersection, intersection); |
|
Mat delta = uni & intersection; |
|
|
|
return countNonZero(delta); |
|
} |
|
|
|
void checkContour(std::vector<Point>& pts, |
|
const bool backward = false, |
|
int allowed_mismatch = 0) |
|
{ |
|
const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); |
|
CV_Assert(test_info); |
|
const std::string name = std::string(cvtest::TS::ptr()->get_data_path() + "imgproc/" + test_info->test_case_name() + "-" + test_info->name() + (backward ? "-backward" : "") + ".xml"); |
|
|
|
std::vector<Point> reference_pts; |
|
#ifdef GENERATE_TEST_DATA |
|
{ |
|
cv::FileStorage fs(name, cv::FileStorage::WRITE); |
|
fs << "pts" << pts; |
|
} |
|
reference_pts = pts; |
|
#else |
|
FileStorage fs(name, FileStorage::READ); |
|
read(fs["pts"], reference_pts, std::vector<Point>()); |
|
#endif |
|
|
|
if (!allowed_mismatch) |
|
EXPECT_EQ(pts, reference_pts); |
|
else |
|
EXPECT_LE(contoursAreaPixelsMismatch(pts, reference_pts), allowed_mismatch); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, rect) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
Mat image = getTestImage1(); |
|
tool.applyImage(image); |
|
|
|
Point source_point(50, 30); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(100, 30); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts); |
|
show(image, pts); |
|
|
|
Mat image2 = getTestImage2(); |
|
tool.applyImage(image2); |
|
|
|
tool.buildMap(source_point); |
|
|
|
std::vector<Point> pts2; |
|
tool.getContour(target_point, pts2, true/*backward*/); |
|
checkContour(pts2, true/*backward*/); |
|
show(image2, pts2); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, lines) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
Mat image = getTestImage3(); |
|
tool.applyImage(image); |
|
|
|
Point source_point(30, 50); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(150, 50); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts); |
|
show(image, pts); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, circles) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
tool.setGradientMagnitudeMaxLimit(10); |
|
|
|
Mat image = getTestImage4(); |
|
tool.applyImage(image); |
|
|
|
Point source_point(50, 50); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(150, 50); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts); |
|
show(image, pts); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, circles_gradient) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
Mat image = getTestImage5(); |
|
tool.applyImage(image); |
|
|
|
Point source_point(50, 50); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(150, 50); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts); |
|
show(image, pts); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, grayscale) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
|
|
Mat image = getTestImageGray(); |
|
tool.applyImage(image); |
|
|
|
Point source_point(275, 63); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(413, 155); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts, false, 2); |
|
show(image, pts); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, check_features_grayscale_1_0_0_zerro_crossing_with_limit) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
tool.setEdgeFeatureZeroCrossingParameters(64); |
|
tool.setWeights(1.0f, 0.0f, 0.0f); |
|
|
|
Mat image = getTestImageGray(); |
|
tool.applyImage(image); |
|
|
|
Point source_point(275, 63); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(413, 155); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts, false, 11); |
|
show(image, pts); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, check_features_grayscale_1_0_0_canny) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
tool.setEdgeFeatureCannyParameters(50, 100); |
|
tool.setWeights(1.0f, 0.0f, 0.0f); |
|
|
|
Mat image = getTestImageGray(); |
|
tool.applyImage(image); |
|
|
|
Point source_point(275, 63); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(413, 155); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts, false, 6); |
|
show(image, pts); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, check_features_grayscale_0_1_0) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
tool.setWeights(0.0f, 1.0f, 0.0f); |
|
|
|
Mat image = getTestImageGray(); |
|
tool.applyImage(image); |
|
|
|
Point source_point(275, 63); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(413, 155); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts, false, 4); |
|
show(image, pts); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, check_features_grayscale_0_0_1) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
tool.setWeights(0.0f, 0.0f, 1.0f); |
|
|
|
Mat image = getTestImageGray(); |
|
tool.applyImage(image); |
|
|
|
Point source_point(275, 63); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(413, 155); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts, false, 2); |
|
show(image, pts); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, color) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
|
|
Mat image = getTestImageColor(); |
|
tool.applyImage(image); |
|
|
|
Point source_point(275, 63); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(413, 155); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts, false, 2); |
|
show(image, pts); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, color_canny) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
tool.setEdgeFeatureCannyParameters(32, 100); |
|
|
|
Mat image = getTestImageColor(); |
|
tool.applyImage(image); |
|
|
|
Point source_point(275, 63); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(413, 155); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts, false, 2); |
|
show(image, pts); |
|
} |
|
|
|
|
|
TEST(Imgproc_IntelligentScissorsMB, color_custom_features_invalid) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
ASSERT_ANY_THROW(tool.applyImageFeatures(noArray(), noArray(), noArray())); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, color_custom_features_edge) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
|
|
Mat image = getTestImageColor(); |
|
|
|
Mat canny_edges; |
|
Canny(image, canny_edges, 32, 100, 5); |
|
Mat binary_edge_feature; |
|
cv::threshold(canny_edges, binary_edge_feature, 254, 1, THRESH_BINARY_INV); |
|
tool.applyImageFeatures(binary_edge_feature, noArray(), noArray(), image); |
|
|
|
Point source_point(275, 63); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(413, 155); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts, false, 2); |
|
show(image, pts); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, color_custom_features_all) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
|
|
tool.setWeights(0.9f, 0.0f, 0.1f); |
|
|
|
Mat image = getTestImageColor(); |
|
|
|
Mat canny_edges; |
|
Canny(image, canny_edges, 50, 100, 5); |
|
Mat binary_edge_feature; // 0, 1 values |
|
cv::threshold(canny_edges, binary_edge_feature, 254, 1, THRESH_BINARY_INV); |
|
|
|
Mat_<Point2f> gradient_direction(image.size(), Point2f(0, 0)); // normalized |
|
Mat_<float> gradient_magnitude(image.size(), 0); // cost function |
|
tool.applyImageFeatures(binary_edge_feature, gradient_direction, gradient_magnitude); |
|
|
|
Point source_point(275, 63); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(413, 155); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts, false, 9); |
|
show(image, pts); |
|
} |
|
|
|
TEST(Imgproc_IntelligentScissorsMB, color_custom_features_edge_magnitude) |
|
{ |
|
segmentation::IntelligentScissorsMB tool; |
|
|
|
tool.setWeights(0.9f, 0.0f, 0.1f); |
|
|
|
Mat image = getTestImageColor(); |
|
|
|
Mat canny_edges; |
|
Canny(image, canny_edges, 50, 100, 5); |
|
Mat binary_edge_feature; // 0, 1 values |
|
cv::threshold(canny_edges, binary_edge_feature, 254, 1, THRESH_BINARY_INV); |
|
|
|
Mat_<float> gradient_magnitude(image.size(), 0); // cost function |
|
tool.applyImageFeatures(binary_edge_feature, noArray(), gradient_magnitude); |
|
|
|
Point source_point(275, 63); |
|
tool.buildMap(source_point); |
|
|
|
Point target_point(413, 155); |
|
std::vector<Point> pts; |
|
tool.getContour(target_point, pts); |
|
checkContour(pts, false, 9); |
|
show(image, pts); |
|
} |
|
|
|
|
|
}} // namespace
|
|
|