mirror of https://github.com/opencv/opencv.git
parent
86c7e183d2
commit
98c92f196e
10 changed files with 4037 additions and 154 deletions
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,256 @@ |
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp" |
||||
|
||||
#ifdef HAVE_CUDA |
||||
|
||||
namespace { |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HoughLines
|
||||
|
||||
PARAM_TEST_CASE(HoughLines, cv::gpu::DeviceInfo, cv::Size, UseRoi) |
||||
{ |
||||
static void generateLines(cv::Mat& img) |
||||
{ |
||||
img.setTo(cv::Scalar::all(0)); |
||||
|
||||
cv::line(img, cv::Point(20, 0), cv::Point(20, img.rows), cv::Scalar::all(255)); |
||||
cv::line(img, cv::Point(0, 50), cv::Point(img.cols, 50), cv::Scalar::all(255)); |
||||
cv::line(img, cv::Point(0, 0), cv::Point(img.cols, img.rows), cv::Scalar::all(255)); |
||||
cv::line(img, cv::Point(img.cols, 0), cv::Point(0, img.rows), cv::Scalar::all(255)); |
||||
} |
||||
|
||||
static void drawLines(cv::Mat& dst, const std::vector<cv::Vec2f>& lines) |
||||
{ |
||||
dst.setTo(cv::Scalar::all(0)); |
||||
|
||||
for (size_t i = 0; i < lines.size(); ++i) |
||||
{ |
||||
float rho = lines[i][0], theta = lines[i][1]; |
||||
cv::Point pt1, pt2; |
||||
double a = std::cos(theta), b = std::sin(theta); |
||||
double x0 = a*rho, y0 = b*rho; |
||||
pt1.x = cvRound(x0 + 1000*(-b)); |
||||
pt1.y = cvRound(y0 + 1000*(a)); |
||||
pt2.x = cvRound(x0 - 1000*(-b)); |
||||
pt2.y = cvRound(y0 - 1000*(a)); |
||||
cv::line(dst, pt1, pt2, cv::Scalar::all(255)); |
||||
} |
||||
} |
||||
}; |
||||
|
||||
TEST_P(HoughLines, Accuracy) |
||||
{ |
||||
const cv::gpu::DeviceInfo devInfo = GET_PARAM(0); |
||||
cv::gpu::setDevice(devInfo.deviceID()); |
||||
const cv::Size size = GET_PARAM(1); |
||||
const bool useRoi = GET_PARAM(2); |
||||
|
||||
const float rho = 1.0f; |
||||
const float theta = 1.5f * CV_PI / 180.0f; |
||||
const int threshold = 100; |
||||
|
||||
cv::Mat src(size, CV_8UC1); |
||||
generateLines(src); |
||||
|
||||
cv::gpu::GpuMat d_lines; |
||||
cv::gpu::HoughLines(loadMat(src, useRoi), d_lines, rho, theta, threshold); |
||||
|
||||
std::vector<cv::Vec2f> lines; |
||||
cv::gpu::HoughLinesDownload(d_lines, lines); |
||||
|
||||
cv::Mat dst(size, CV_8UC1); |
||||
drawLines(dst, lines); |
||||
|
||||
ASSERT_MAT_NEAR(src, dst, 0.0); |
||||
} |
||||
|
||||
INSTANTIATE_TEST_CASE_P(GPU_ImgProc, HoughLines, testing::Combine( |
||||
ALL_DEVICES, |
||||
DIFFERENT_SIZES, |
||||
WHOLE_SUBMAT)); |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HoughCircles
|
||||
|
||||
PARAM_TEST_CASE(HoughCircles, cv::gpu::DeviceInfo, cv::Size, UseRoi) |
||||
{ |
||||
static void drawCircles(cv::Mat& dst, const std::vector<cv::Vec3f>& circles, bool fill) |
||||
{ |
||||
dst.setTo(cv::Scalar::all(0)); |
||||
|
||||
for (size_t i = 0; i < circles.size(); ++i) |
||||
cv::circle(dst, cv::Point2f(circles[i][0], circles[i][1]), (int)circles[i][2], cv::Scalar::all(255), fill ? -1 : 1); |
||||
} |
||||
}; |
||||
|
||||
TEST_P(HoughCircles, Accuracy) |
||||
{ |
||||
const cv::gpu::DeviceInfo devInfo = GET_PARAM(0); |
||||
cv::gpu::setDevice(devInfo.deviceID()); |
||||
const cv::Size size = GET_PARAM(1); |
||||
const bool useRoi = GET_PARAM(2); |
||||
|
||||
const float dp = 2.0f; |
||||
const float minDist = 10.0f; |
||||
const int minRadius = 10; |
||||
const int maxRadius = 20; |
||||
const int cannyThreshold = 100; |
||||
const int votesThreshold = 20; |
||||
|
||||
std::vector<cv::Vec3f> circles_gold(4); |
||||
circles_gold[0] = cv::Vec3i(20, 20, minRadius); |
||||
circles_gold[1] = cv::Vec3i(90, 87, minRadius + 3); |
||||
circles_gold[2] = cv::Vec3i(30, 70, minRadius + 8); |
||||
circles_gold[3] = cv::Vec3i(80, 10, maxRadius); |
||||
|
||||
cv::Mat src(size, CV_8UC1); |
||||
drawCircles(src, circles_gold, true); |
||||
|
||||
cv::gpu::GpuMat d_circles; |
||||
cv::gpu::HoughCircles(loadMat(src, useRoi), d_circles, CV_HOUGH_GRADIENT, dp, minDist, cannyThreshold, votesThreshold, minRadius, maxRadius); |
||||
|
||||
std::vector<cv::Vec3f> circles; |
||||
cv::gpu::HoughCirclesDownload(d_circles, circles); |
||||
|
||||
ASSERT_FALSE(circles.empty()); |
||||
|
||||
for (size_t i = 0; i < circles.size(); ++i) |
||||
{ |
||||
cv::Vec3f cur = circles[i]; |
||||
|
||||
bool found = false; |
||||
|
||||
for (size_t j = 0; j < circles_gold.size(); ++j) |
||||
{ |
||||
cv::Vec3f gold = circles_gold[j]; |
||||
|
||||
if (std::fabs(cur[0] - gold[0]) < minDist && std::fabs(cur[1] - gold[1]) < minDist && std::fabs(cur[2] - gold[2]) < minDist) |
||||
{ |
||||
found = true; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
ASSERT_TRUE(found); |
||||
} |
||||
} |
||||
|
||||
INSTANTIATE_TEST_CASE_P(GPU_ImgProc, HoughCircles, testing::Combine( |
||||
ALL_DEVICES, |
||||
DIFFERENT_SIZES, |
||||
WHOLE_SUBMAT)); |
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// GeneralizedHough
|
||||
|
||||
PARAM_TEST_CASE(GeneralizedHough, cv::gpu::DeviceInfo, UseRoi) |
||||
{ |
||||
}; |
||||
|
||||
TEST_P(GeneralizedHough, POSITION) |
||||
{ |
||||
const cv::gpu::DeviceInfo devInfo = GET_PARAM(0); |
||||
cv::gpu::setDevice(devInfo.deviceID()); |
||||
const bool useRoi = GET_PARAM(1); |
||||
|
||||
cv::Mat templ = readImage("../cv/shared/templ.png", cv::IMREAD_GRAYSCALE); |
||||
ASSERT_FALSE(templ.empty()); |
||||
|
||||
cv::Point templCenter(templ.cols / 2, templ.rows / 2); |
||||
|
||||
const size_t gold_count = 3; |
||||
cv::Point pos_gold[gold_count]; |
||||
pos_gold[0] = cv::Point(templCenter.x + 10, templCenter.y + 10); |
||||
pos_gold[1] = cv::Point(2 * templCenter.x + 40, templCenter.y + 10); |
||||
pos_gold[2] = cv::Point(2 * templCenter.x + 40, 2 * templCenter.y + 40); |
||||
|
||||
cv::Mat image(templ.rows * 3, templ.cols * 3, CV_8UC1, cv::Scalar::all(0)); |
||||
for (size_t i = 0; i < gold_count; ++i) |
||||
{ |
||||
cv::Rect rec(pos_gold[i].x - templCenter.x, pos_gold[i].y - templCenter.y, templ.cols, templ.rows); |
||||
cv::Mat imageROI = image(rec); |
||||
templ.copyTo(imageROI); |
||||
} |
||||
|
||||
cv::Ptr<cv::gpu::GeneralizedHough_GPU> hough = cv::gpu::GeneralizedHough_GPU::create(cv::GHT_POSITION); |
||||
hough->set("votesThreshold", 200); |
||||
|
||||
hough->setTemplate(loadMat(templ, useRoi)); |
||||
|
||||
cv::gpu::GpuMat d_pos; |
||||
hough->detect(loadMat(image, useRoi), d_pos); |
||||
|
||||
std::vector<cv::Vec4f> pos; |
||||
hough->download(d_pos, pos); |
||||
|
||||
ASSERT_EQ(gold_count, pos.size()); |
||||
|
||||
for (size_t i = 0; i < gold_count; ++i) |
||||
{ |
||||
cv::Point gold = pos_gold[i]; |
||||
|
||||
bool found = false; |
||||
|
||||
for (size_t j = 0; j < pos.size(); ++j) |
||||
{ |
||||
cv::Point2f p(pos[j][0], pos[j][1]); |
||||
|
||||
if (::fabs(p.x - gold.x) < 2 && ::fabs(p.y - gold.y) < 2) |
||||
{ |
||||
found = true; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
ASSERT_TRUE(found); |
||||
} |
||||
} |
||||
|
||||
INSTANTIATE_TEST_CASE_P(GPU_ImgProc, GeneralizedHough, testing::Combine( |
||||
ALL_DEVICES, |
||||
WHOLE_SUBMAT)); |
||||
|
||||
} // namespace
|
||||
|
||||
#endif // HAVE_CUDA
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,209 @@ |
||||
#include <vector> |
||||
#include <iostream> |
||||
#include <string> |
||||
|
||||
#include "opencv2/core/core.hpp" |
||||
#include "opencv2/imgproc/imgproc.hpp" |
||||
#include "opencv2/gpu/gpu.hpp" |
||||
#include "opencv2/highgui/highgui.hpp" |
||||
#include "opencv2/contrib/contrib.hpp" |
||||
|
||||
using namespace std; |
||||
using namespace cv; |
||||
using namespace cv::gpu; |
||||
|
||||
static Mat loadImage(const string& name) |
||||
{ |
||||
Mat image = imread(name, IMREAD_GRAYSCALE); |
||||
if (image.empty()) |
||||
{ |
||||
cerr << "Can't load image - " << name << endl; |
||||
exit(-1); |
||||
} |
||||
return image; |
||||
} |
||||
|
||||
int main(int argc, const char* argv[]) |
||||
{ |
||||
CommandLineParser cmd(argc, argv, |
||||
"{ image i | pic1.png | input image }" |
||||
"{ template t | templ.png | template image }" |
||||
"{ scale s | | estimate scale }" |
||||
"{ rotation r | | estimate rotation }" |
||||
"{ gpu | | use gpu version }" |
||||
"{ minDist | 100 | minimum distance between the centers of the detected objects }" |
||||
"{ levels | 360 | R-Table levels }" |
||||
"{ votesThreshold | 30 | the accumulator threshold for the template centers at the detection stage. The smaller it is, the more false positions may be detected }" |
||||
"{ angleThresh | 10000 | angle votes treshold }" |
||||
"{ scaleThresh | 1000 | scale votes treshold }" |
||||
"{ posThresh | 100 | position votes threshold }" |
||||
"{ dp | 2 | inverse ratio of the accumulator resolution to the image resolution }" |
||||
"{ minScale | 0.5 | minimal scale to detect }" |
||||
"{ maxScale | 2 | maximal scale to detect }" |
||||
"{ scaleStep | 0.05 | scale step }" |
||||
"{ minAngle | 0 | minimal rotation angle to detect in degrees }" |
||||
"{ maxAngle | 360 | maximal rotation angle to detect in degrees }" |
||||
"{ angleStep | 1 | angle step in degrees }" |
||||
"{ maxSize | 1000 | maximal size of inner buffers }" |
||||
"{ help h ? | | print help message }" |
||||
); |
||||
|
||||
cmd.about("This program demonstrates arbitary object finding with the Generalized Hough transform."); |
||||
|
||||
if (cmd.has("help")) |
||||
{ |
||||
cmd.printMessage(); |
||||
return 0; |
||||
} |
||||
|
||||
const string templName = cmd.get<string>("template"); |
||||
const string imageName = cmd.get<string>("image"); |
||||
const bool estimateScale = cmd.has("scale"); |
||||
const bool estimateRotation = cmd.has("rotation"); |
||||
const bool useGpu = cmd.has("gpu"); |
||||
const double minDist = cmd.get<double>("minDist"); |
||||
const int levels = cmd.get<int>("levels"); |
||||
const int votesThreshold = cmd.get<int>("votesThreshold"); |
||||
const int angleThresh = cmd.get<int>("angleThresh"); |
||||
const int scaleThresh = cmd.get<int>("scaleThresh"); |
||||
const int posThresh = cmd.get<int>("posThresh"); |
||||
const double dp = cmd.get<double>("dp"); |
||||
const double minScale = cmd.get<double>("minScale"); |
||||
const double maxScale = cmd.get<double>("maxScale"); |
||||
const double scaleStep = cmd.get<double>("scaleStep"); |
||||
const double minAngle = cmd.get<double>("minAngle"); |
||||
const double maxAngle = cmd.get<double>("maxAngle"); |
||||
const double angleStep = cmd.get<double>("angleStep"); |
||||
const int maxSize = cmd.get<int>("maxSize"); |
||||
|
||||
if (!cmd.check()) |
||||
{ |
||||
cmd.printErrors(); |
||||
return -1; |
||||
} |
||||
|
||||
Mat templ = loadImage(templName); |
||||
Mat image = loadImage(imageName); |
||||
|
||||
int method = GHT_POSITION; |
||||
if (estimateScale) |
||||
method += GHT_SCALE; |
||||
if (estimateRotation) |
||||
method += GHT_ROTATION; |
||||
|
||||
vector<Vec4f> position; |
||||
cv::TickMeter tm; |
||||
|
||||
if (useGpu) |
||||
{ |
||||
GpuMat d_templ(templ); |
||||
GpuMat d_image(image); |
||||
GpuMat d_position; |
||||
|
||||
Ptr<GeneralizedHough_GPU> d_hough = GeneralizedHough_GPU::create(method); |
||||
d_hough->set("minDist", minDist); |
||||
d_hough->set("levels", levels); |
||||
d_hough->set("dp", dp); |
||||
d_hough->set("maxSize", maxSize); |
||||
if (estimateScale && estimateRotation) |
||||
{ |
||||
d_hough->set("angleThresh", angleThresh); |
||||
d_hough->set("scaleThresh", scaleThresh); |
||||
d_hough->set("posThresh", posThresh); |
||||
} |
||||
else |
||||
{ |
||||
d_hough->set("votesThreshold", votesThreshold); |
||||
} |
||||
if (estimateScale) |
||||
{ |
||||
d_hough->set("minScale", minScale); |
||||
d_hough->set("maxScale", maxScale); |
||||
d_hough->set("scaleStep", scaleStep); |
||||
} |
||||
if (estimateRotation) |
||||
{ |
||||
d_hough->set("minAngle", minAngle); |
||||
d_hough->set("maxAngle", maxAngle); |
||||
d_hough->set("angleStep", angleStep); |
||||
} |
||||
|
||||
d_hough->setTemplate(d_templ); |
||||
|
||||
tm.start(); |
||||
|
||||
d_hough->detect(d_image, d_position); |
||||
d_hough->download(d_position, position); |
||||
|
||||
tm.stop(); |
||||
} |
||||
else |
||||
{ |
||||
Ptr<GeneralizedHough> hough = GeneralizedHough::create(method); |
||||
hough->set("minDist", minDist); |
||||
hough->set("levels", levels); |
||||
hough->set("dp", dp); |
||||
if (estimateScale && estimateRotation) |
||||
{ |
||||
hough->set("angleThresh", angleThresh); |
||||
hough->set("scaleThresh", scaleThresh); |
||||
hough->set("posThresh", posThresh); |
||||
hough->set("maxSize", maxSize); |
||||
} |
||||
else |
||||
{ |
||||
hough->set("votesThreshold", votesThreshold); |
||||
} |
||||
if (estimateScale) |
||||
{ |
||||
hough->set("minScale", minScale); |
||||
hough->set("maxScale", maxScale); |
||||
hough->set("scaleStep", scaleStep); |
||||
} |
||||
if (estimateRotation) |
||||
{ |
||||
hough->set("minAngle", minAngle); |
||||
hough->set("maxAngle", maxAngle); |
||||
hough->set("angleStep", angleStep); |
||||
} |
||||
|
||||
hough->setTemplate(templ); |
||||
|
||||
tm.start(); |
||||
|
||||
hough->detect(image, position); |
||||
|
||||
tm.stop(); |
||||
} |
||||
|
||||
cout << "Found : " << position.size() << " objects" << endl; |
||||
cout << "Detection time : " << tm.getTimeMilli() << " ms" << endl; |
||||
|
||||
Mat out; |
||||
cvtColor(image, out, COLOR_GRAY2BGR); |
||||
|
||||
for (size_t i = 0; i < position.size(); ++i) |
||||
{ |
||||
Point2f pos(position[i][0], position[i][1]); |
||||
float scale = position[i][2]; |
||||
float angle = position[i][3]; |
||||
|
||||
RotatedRect rect; |
||||
rect.center = pos; |
||||
rect.size = Size2f(templ.cols * scale, templ.rows * scale); |
||||
rect.angle = angle; |
||||
|
||||
Point2f pts[4]; |
||||
rect.points(pts); |
||||
|
||||
line(out, pts[0], pts[1], Scalar(0, 0, 255), 3); |
||||
line(out, pts[1], pts[2], Scalar(0, 0, 255), 3); |
||||
line(out, pts[2], pts[3], Scalar(0, 0, 255), 3); |
||||
line(out, pts[3], pts[0], Scalar(0, 0, 255), 3); |
||||
} |
||||
|
||||
imshow("out", out); |
||||
waitKey(); |
||||
|
||||
return 0; |
||||
} |
After Width: | Height: | Size: 1.6 KiB |
Loading…
Reference in new issue