generalized_hough.cpp 6.71 KB
Newer Older
wester committed
1 2 3 4
#include <vector>
#include <iostream>
#include <string>

wester committed
5 6 7 8 9
#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"
a  
Kai Westerkamp committed
10

wester committed
11 12
using namespace std;
using namespace cv;
wester committed
13
using namespace cv::gpu;
wester committed
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

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,
wester committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
        "{ i | image          | pic1.png  | input image }"
        "{ t | template       | templ.png | template image }"
        "{ s | scale          |           | estimate scale }"
        "{ r | rotation       |           | 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 }"
        "{ h | help           |           | print help message }"
wester committed
49 50
    );

wester committed
51
    //cmd.about("This program demonstrates arbitary object finding with the Generalized Hough transform.");
wester committed
52

wester committed
53
    if (cmd.get<bool>("help"))
wester committed
54
    {
wester committed
55
        cmd.printParams();
wester committed
56 57 58 59 60
        return 0;
    }

    const string templName = cmd.get<string>("template");
    const string imageName = cmd.get<string>("image");
wester committed
61 62 63
    const bool estimateScale = cmd.get<bool>("scale");
    const bool estimateRotation = cmd.get<bool>("rotation");
    const bool useGpu = cmd.get<bool>("gpu");
wester committed
64 65 66 67 68 69 70 71 72 73 74 75 76
    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");
wester committed
77
    const int maxSize = cmd.get<int>("maxSize");
wester committed
78 79 80 81

    Mat templ = loadImage(templName);
    Mat image = loadImage(imageName);

wester committed
82 83 84 85 86
    int method = GHT_POSITION;
    if (estimateScale)
        method += GHT_SCALE;
    if (estimateRotation)
        method += GHT_ROTATION;
wester committed
87 88

    vector<Vec4f> position;
wester committed
89
    cv::TickMeter tm;
wester committed
90 91 92

    if (useGpu)
    {
wester committed
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
        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);
wester committed
126 127 128

        tm.start();

wester committed
129 130
        d_hough->detect(d_image, d_position);
        d_hough->download(d_position, position);
wester committed
131 132 133 134 135

        tm.stop();
    }
    else
    {
wester committed
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
        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);
wester committed
165 166 167

        tm.start();

wester committed
168
        hough->detect(image, position);
wester committed
169 170 171 172 173 174 175 176

        tm.stop();
    }

    cout << "Found : " << position.size() << " objects" << endl;
    cout << "Detection time : " << tm.getTimeMilli() << " ms" << endl;

    Mat out;
wester committed
177
    cvtColor(image, out, COLOR_GRAY2BGR);
wester committed
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203

    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;
}