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.
210 lines
6.8 KiB
210 lines
6.8 KiB
#include <vector> |
|
#include <iostream> |
|
#include <string> |
|
|
|
#include "opencv2/core.hpp" |
|
#include "opencv2/core/utility.hpp" |
|
#include "opencv2/imgproc.hpp" |
|
#include "opencv2/gpu.hpp" |
|
#include "opencv2/highgui.hpp" |
|
#include "opencv2/contrib.hpp" |
|
|
|
using namespace std; |
|
using namespace cv; |
|
using cv::gpu::GpuMat; |
|
|
|
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 = cv::GeneralizedHough::GHT_POSITION; |
|
if (estimateScale) |
|
method += cv::GeneralizedHough::GHT_SCALE; |
|
if (estimateRotation) |
|
method += cv::GeneralizedHough::GHT_ROTATION; |
|
|
|
vector<Vec4f> position; |
|
cv::TickMeter tm; |
|
|
|
if (useGpu) |
|
{ |
|
GpuMat d_templ(templ); |
|
GpuMat d_image(image); |
|
GpuMat d_position; |
|
|
|
Ptr<gpu::GeneralizedHough> d_hough = gpu::GeneralizedHough::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->downloadResults(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; |
|
cv::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; |
|
}
|
|
|